{ "openapi": "3.1.0", "info": { "title": "Voucherify Loyalty v2 API", "version": "2.0.0", "description": "Complete OpenAPI specification for the Voucherify Loyalty v2 API.\nAll endpoints require the LOYALTY_V2 feature flag.\n\nCombined from per-domain specs: programs.yaml, members.yaml, program-operations.yaml, card-definitions.yaml, earning-rules.yaml, tier-structures.yaml, benefits.yaml, rewards.yaml, examine.yaml" }, "servers": [ { "url": "{protocol}://{host}", "variables": { "protocol": { "default": "https", "enum": [ "https", "http" ] }, "host": { "default": "api.voucherify.io" } } } ], "tags": [ { "name": "Programs", "description": "Loyalty program CRUD, lifecycle management, program-scoped resource assignments (card definitions, earning rules, rewards, tier structures), member management (create, list, get, update, activate, deactivate, delete), card operations (points adjustment, pending points, expiring points, transactions), reward purchases, and activity history." }, { "name": "Card Definitions", "description": "CRUD operations, lifecycle management, and activity history for card definitions. Card definitions describe the configuration for loyalty cards, including code generation, points expiration, earning/spending limits, pending points, refunds, and balance settings." }, { "name": "Earning Rules", "description": "Manage earning rules that define how customers earn points or receive incentives based on triggers (events, segments, custom events). Includes CRUD, lifecycle, and activity history." }, { "name": "Tier Structures", "description": "CRUD operations, lifecycle management, and activity history for tier structures. Includes nested tier definitions (create, list, update, delete) within tier structures. Tier structures define the tiering model for loyalty programs — how members qualify for and move between tiers." }, { "name": "Benefits", "description": "Manage benefit definitions (fixed points, proportional points, material, digital). Includes CRUD, lifecycle transitions, and activity history." }, { "name": "Rewards", "description": "CRUD, lifecycle operations, and activity history for reward definitions. Rewards can be material (product/SKU) or digital (discount coupons, gift vouchers)." }, { "name": "Examine", "description": "Evaluation endpoints that estimate earning opportunities and reward availability for a customer across their loyalty program memberships, without side effects." } ], "paths": { "/v2/loyalties/programs": { "post": { "operationId": "createProgram", "tags": [ "Programs" ], "summary": "Create program", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nCreates a new loyalty program. The program can be created with status `DRAFT` (default) or\n`ACTIVE`. When created as `ACTIVE`, the program must be connected to at least one active\ncard definition and at least one active earning rule (provided via `card_definitions` and\n`earning_rules` arrays), otherwise the request is rejected with `423 Locked`\n(keys `missing_active_card_definition` / `missing_active_earning_rule`).\nOptionally assigns card definitions, earning rules, rewards and tier structures in the same request.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramCreateRequest" } } } }, "responses": { "200": { "description": "Program created. Response includes the ids of resources assigned during creation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramCreateResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "get": { "operationId": "listPrograms", "tags": [ "Programs" ], "summary": "List programs", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of loyalty programs. Supports filtering by `id`, `name`,\n`status` and `created_at`. The same field cannot be used in both ascending and descending\norder at once.", "parameters": [ { "name": "filters", "in": "query", "required": false, "description": "Filters for the program list. Nested object serialized in the query string\n(e.g. `filters[status][conditions][$is]=ACTIVE`). Each field accepts a `conditions`\nobject with at least one condition. Only the condition operators supported by each\nfield type are allowed.", "style": "deepObject", "explode": true, "schema": { "oneOf": [ { "$ref": "#/components/schemas/ProgramListFilters" }, { "type": "null" } ] } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items to return. Between 1 and 100. Defaults to 10. Non-integer values are rounded.", "schema": { "type": [ "number", "string", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sorting order. A single value or an array of values. Prefix a field with `-` for\ndescending order. Defaults to `-created_at`. The same field cannot be used in both\nascending and descending order at once.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at", "name", "-name" ] } }, { "type": "string", "enum": [ "-created_at", "created_at", "name", "-name" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned by a previous call (`cursor.next`).", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsprg_[a-f0-9]+$" } } ], "responses": { "200": { "description": "Paginated list of programs.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}": { "get": { "operationId": "getProgram", "tags": [ "Programs" ], "summary": "Get program", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a single loyalty program by its id.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The program.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Program" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "put": { "operationId": "updateProgram", "tags": [ "Programs" ], "summary": "Update program", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nUpdates a loyalty program. When the program is not in `DRAFT` status, only `name` and\n`metadata` may be changed (other properties are restricted after leaving draft).", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramUpdateRequest" } } } }, "responses": { "200": { "description": "The updated program.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Program" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "operationId": "deleteProgram", "tags": [ "Programs" ], "summary": "Delete program", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nSoft-deletes a loyalty program and removes all of its card definition, earning rule,\nreward and tier structure assignments.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The deleted program.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Program" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/activate": { "post": { "operationId": "activateProgram", "tags": [ "Programs" ], "summary": "Activate program", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nTransitions the program to `ACTIVE` status. Allowed transitions to `ACTIVE` are from\n`DRAFT` and `INACTIVE`. Before activation the program's card definition, earning rule\nand tier structure assignments are validated (at least one active card definition and\nearning rule is required). An invalid state transition is rejected with `400`\n(key `invalid_state_transition`). No request body.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The activated program.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Program" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/deactivate": { "post": { "operationId": "deactivateProgram", "tags": [ "Programs" ], "summary": "Deactivate program", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nTransitions the program to `INACTIVE` status. Only an `ACTIVE` program can be deactivated.\nAn invalid state transition is rejected with `400` (key `invalid_state_transition`).\nNo request body.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The deactivated program.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Program" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/activities": { "get": { "operationId": "listProgramActivities", "tags": [ "Programs" ], "summary": "List program activities", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of activities recorded for a program (created, updated,\ndeleted, activated, deactivated and assignment changes). Supports filtering by activity\n`id`, `type` and `created_at`.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "description": "Filters for the activity list. Nested object serialized in the query string\n(e.g. `filters[type][conditions][$is]=vl.program.created`). Only the condition\noperators supported by each field type are allowed.", "style": "deepObject", "explode": true, "schema": { "oneOf": [ { "$ref": "#/components/schemas/ProgramActivityListFilters" }, { "type": "null" } ] } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items to return. Between 1 and 100. Defaults to 10. Non-integer values are rounded.", "schema": { "type": [ "number", "string", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sorting order. A single value or an array of values. Prefix with `-` for descending.\nDefaults to `-created_at`. The same field cannot be used in both ascending and\ndescending order at once.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "created_at", "-created_at" ] } }, { "type": "string", "enum": [ "created_at", "-created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned by a previous call (`cursor.next`).", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsapr_[a-f0-9]+$" } } ], "responses": { "200": { "description": "Paginated list of program activities.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramActivityListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/card-definitions": { "get": { "operationId": "listProgramCardDefinitionAssignments", "tags": [ "Programs" ], "summary": "List program card definition assignments", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of card definitions assigned to the program.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items to return. Between 1 and 100. Defaults to 10. Non-integer values are rounded.", "schema": { "type": [ "number", "string", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sorting order. A single value or an array of values. Prefix with `-` for descending.\nDefaults to `-created_at`. The same field cannot be used in both ascending and\ndescending order at once.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at" ] } }, { "type": "string", "enum": [ "-created_at", "created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned by a previous call (`cursor.next`).", "schema": { "type": [ "string", "null" ], "pattern": "^lcrscdefa_[a-f0-9]+$" } } ], "responses": { "200": { "description": "Paginated list of card definition assignments.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramCardDefinitionAssignmentListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/card-definitions/batch": { "post": { "operationId": "batchProgramCardDefinitionAssignments", "tags": [ "Programs" ], "summary": "Batch assign/unassign card definitions", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nAssigns and/or unassigns card definitions to/from a program in a single batch.\nUnassign operations are processed before assign operations.\nThe program must be in `DRAFT` status - otherwise the request is rejected with\n`423 Locked` (key `non_draft_program`). In strict mode (default) missing card\ndefinitions, inactive card definitions or missing assignments cause the whole\nbatch to fail.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramCardDefinitionBatchRequest" } } } }, "responses": { "200": { "description": "Batch processing result.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramCardDefinitionBatchResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/earning-rules": { "get": { "operationId": "listProgramEarningRuleAssignments", "tags": [ "Programs" ], "summary": "List program earning rule assignments", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of earning rules assigned to the program.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items to return. Between 1 and 100. Defaults to 10. Non-integer values are rounded.", "schema": { "type": [ "number", "string", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sorting order. A single value or an array of values. Prefix with `-` for descending.\nDefaults to `-created_at`. The same field cannot be used in both ascending and\ndescending order at once.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at" ] } }, { "type": "string", "enum": [ "-created_at", "created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned by a previous call (`cursor.next`).", "schema": { "type": [ "string", "null" ], "pattern": "^lcrserna_[a-f0-9]+$" } } ], "responses": { "200": { "description": "Paginated list of earning rule assignments.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramEarningRuleAssignmentListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/earning-rules/batch": { "post": { "operationId": "batchProgramEarningRuleAssignments", "tags": [ "Programs" ], "summary": "Batch assign/unassign earning rules", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nAssigns and/or unassigns earning rules to/from a program in a single batch.\nUnassign operations are processed before assign operations. When the program is\n`ACTIVE`, the batch is validated to leave at least one active earning rule assigned.\nIn strict mode (default) missing earning rules or missing assignments cause the whole\nbatch to fail.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramEarningRuleBatchRequest" } } } }, "responses": { "200": { "description": "Batch processing result.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramEarningRuleBatchResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/tier-structures": { "get": { "operationId": "listProgramTierStructureAssignments", "tags": [ "Programs" ], "summary": "List program tier structure assignments", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of tier structures assigned to the program.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items to return. Between 1 and 100. Defaults to 10. Non-integer values are rounded.", "schema": { "type": [ "number", "string", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sorting order. A single value or an array of values. Prefix with `-` for descending.\nDefaults to `-created_at`. The same field cannot be used in both ascending and\ndescending order at once.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at" ] } }, { "type": "string", "enum": [ "-created_at", "created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned by a previous call (`cursor.next`).", "schema": { "type": [ "string", "null" ], "pattern": "^lcrstsa_[a-f0-9]+$" } } ], "responses": { "200": { "description": "Paginated list of tier structure assignments.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramTierStructureAssignmentListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/tier-structures/batch": { "post": { "operationId": "batchProgramTierStructureAssignments", "tags": [ "Programs" ], "summary": "Batch assign/unassign tier structures", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nAssigns and/or unassigns tier structures to/from a program in a single batch.\nUnassign operations are processed before assign operations. Unassigning is only\nallowed while the program is in `DRAFT` status - otherwise the request is rejected\nwith `423 Locked` (key `non_draft_program`). A program can have at most one tier\nstructure assigned. In strict mode (default) missing tier structures, inactive tier\nstructures or missing assignments cause the whole batch to fail.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramTierStructureBatchRequest" } } } }, "responses": { "200": { "description": "Batch processing result.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramTierStructureBatchResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/rewards": { "get": { "operationId": "listProgramRewardAssignments", "tags": [ "Programs" ], "summary": "List program reward assignments", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of rewards assigned to the program, including their stock configuration and redemption counters.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items to return. Between 1 and 100. Defaults to 10. Non-integer values are rounded.", "schema": { "type": [ "number", "string", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sorting order. A single value or an array of values. Prefix with `-` for descending.\nDefaults to `-created_at`. The same field cannot be used in both ascending and\ndescending order at once.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at" ] } }, { "type": "string", "enum": [ "-created_at", "created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned by a previous call (`cursor.next`).", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsrewa_[a-f0-9]+$" } } ], "responses": { "200": { "description": "Paginated list of reward assignments.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramRewardAssignmentListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/rewards/batch": { "post": { "operationId": "batchProgramRewardAssignments", "tags": [ "Programs" ], "summary": "Batch assign/unassign rewards", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nAssigns and/or unassigns rewards to/from a program in a single batch.\nUnassign operations are processed before assign operations. Each reward to assign\nmust include its `stock` configuration. In strict mode (default) missing rewards\nor missing assignments cause the whole batch to fail (`404 Not Found`).", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramRewardBatchRequest" } } } }, "responses": { "200": { "description": "Batch processing result.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramRewardBatchResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/rewards/{rewardId}": { "put": { "operationId": "updateProgramRewardAssignment", "tags": [ "Programs" ], "summary": "Update program reward assignment", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nUpdates the stock configuration of a reward assigned to a program.\nReturns the updated reward assignment.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique program identifier.", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "rewardId", "in": "path", "required": true, "description": "Unique reward identifier.", "schema": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramRewardAssignmentUpdateRequest" } } } }, "responses": { "200": { "description": "The updated reward assignment.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProgramRewardAssignment" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members": { "post": { "operationId": "createProgramMember", "tags": [ "Programs" ], "summary": "Create a program member", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nEnrolls a customer as a member of the loyalty program. The program must be in\n`ACTIVE` status (423 otherwise) and the customer must exist. A customer can be a\nmember of a given program only once - creating a second member for the same\ncustomer returns 409 (`member_already_exists`).\n\nLoyalty cards are created automatically for all card definitions assigned to the\nprogram and returned in the `cards` array. Card `code` generation is asynchronous -\n`code` may be `null` immediately after creation.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MemberCreateRequest" } } } }, "responses": { "200": { "description": "The created member with its automatically created cards.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MemberWithCards" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "Member not found": { "value": { "code": 404, "key": "not_found", "message": "Resource not found", "details": "Cannot find member with id lmbr_128f962dbc8c4ba5d", "request_id": "v-12bdef050f2cb1ef71", "resource_id": "lmbr_128f962dbc8c4ba5d", "resource_type": "member" } } } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "get": { "operationId": "listProgramMembers", "tags": [ "Programs" ], "summary": "List program members", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of members of the program. Results can be filtered\nby id, status, customer_id and created_at, and ordered by created_at, status or\ncustomer_id (ascending or descending). The same field cannot be ordered both\nascending and descending at the same time.\nReturns 404 when the program does not exist.\n\nList items do not include the `cards` array - use the get-member endpoint to\nretrieve a member with cards.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of members to return. Must be between 1 and 100. Defaults to 10 when not provided.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Field(s) to order results by. Prefix with `-` for descending order. Accepts a\nsingle value or an array of values. Defaults to `-created_at`. Ordering by the\nsame field in both directions simultaneously is rejected.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at", "status", "-status", "customer_id", "-customer_id" ] } }, { "type": "string", "enum": [ "-created_at", "created_at", "status", "-status", "customer_id", "-customer_id" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.\nMust match the pattern `^lcrsmbr_[a-f0-9]+$`.", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsmbr_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field-specific filter conditions, passed as a deep object, e.g.\n`filters[status][conditions][$is]=ACTIVE`. See the `MemberListFilters` schema\nfor available fields and conditions.", "schema": { "oneOf": [ { "$ref": "#/components/schemas/MemberListFilters" }, { "type": "null" } ] } } ], "responses": { "200": { "description": "Cursor-paginated list of members.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MemberListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/batch": { "post": { "operationId": "batchCreateProgramMembers", "tags": [ "Programs" ], "summary": "Batch create program members", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nSchedules asynchronous batch creation of program members. The request body is a\nJSON array of member entries (maximum body size 10485760 bytes / 10 MB). The\nrequest is processed asynchronously in batches of 100 entries.\n\nThe program must exist (404) and be in `ACTIVE` status (423). Each entry is\nvalidated during background processing the same way as single member creation;\nentries that fail validation (missing/invalid `customer_id`, unknown customer,\ninvalid `status`, member already exists) are reported per-entry in the async action\nresult and do not fail the whole batch (conflicting members are skipped).\n\nReturns 202 with the identifier of the scheduled async action.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MemberBatchCreateRequest" } } } }, "responses": { "202": { "description": "Batch creation has been scheduled.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MemberBatchScheduleResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}": { "get": { "operationId": "getProgramMember", "tags": [ "Programs" ], "summary": "Get a program member", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a single member of the program together with all its loyalty cards.\nEach card includes the current balance, lifetime bucket counters, and next\nexpiration/activation info.\n\nCard `code` may be `null` shortly after member creation because card code\ngeneration is asynchronous.\n\nReturns 404 when the program or member does not exist.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The member with its cards.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MemberWithCards" }, "examples": { "Get member with cards": { "value": { "id": "lmbr_128f962dbc8c4ba5dc", "customer_id": "cust_6onRrs4kCnvSVrTs5YtDPFBG", "program_id": "lprg_128f58429f4c4bf7b2", "status": "ACTIVE", "metadata": {}, "created_at": "2026-06-11T15:59:41.298Z", "updated_at": null, "object": "member", "cards": [ { "member_role": "OWNER", "created_at": "2026-06-11T15:59:41.303Z", "card": { "id": "lcrd_128f962dbd8c4ba5df", "card_definition_id": "lcdef_128f495f720c4bec8c", "card_type": "INDIVIDUAL", "code": "SummerTime-7z8dWawICd", "lifetime_bucket": { "points": { "total": 740, "earned": 40, "added": 700, "purchased": 0, "purchased_reversed": 0, "subtracted": 30, "expired": 300, "spent": 250, "refunded": 0, "returned": 0, "locked": 250, "unlocked": 250 }, "pending_points": { "total": 160, "activated": 40, "canceled": 0 } }, "balance": { "points": 160, "pending_points": 120 }, "next_expiration": { "points": 160, "date": "2026-08-08" }, "next_activation": { "points": 10, "type": "PERIOD_BASED", "date": "2026-07-20" }, "object": "card" }, "object": "member_card" }, { "member_role": "OWNER", "created_at": "2026-06-11T15:59:41.303Z", "card": { "id": "lcrd_128f962dbd8c4ba5e0", "card_definition_id": "lcdef_128f49963c0c4becb7", "card_type": "INDIVIDUAL", "code": "AutumnTime-R02hVARx33", "lifetime_bucket": { "points": { "total": 50, "earned": 0, "added": 50, "purchased": 0, "purchased_reversed": 0, "subtracted": 0, "expired": 0, "spent": 0, "refunded": 0, "returned": 0, "locked": 0, "unlocked": 0 }, "pending_points": { "total": 160, "activated": 0, "canceled": 0 } }, "balance": { "points": 50, "pending_points": 160 }, "next_expiration": { "points": 50, "date": "2026-12-23" }, "next_activation": { "points": 160, "type": "FIXED_DATES", "date": "2026-12-23" }, "object": "card" }, "object": "member_card" }, { "member_role": "OWNER", "created_at": "2026-06-11T15:59:41.303Z", "card": { "id": "lcrd_128f962dbd8c4ba5e1", "card_definition_id": "lcdef_128f4a88414c4bed69", "card_type": "INDIVIDUAL", "code": "AnnualTime-7M7ShPGfme", "lifetime_bucket": { "points": { "total": 1250, "earned": 250, "added": 1000, "purchased": 0, "purchased_reversed": 0, "subtracted": 1000, "expired": 0, "spent": 150, "refunded": 0, "returned": 0, "locked": 10, "unlocked": 10 }, "pending_points": { "total": 300, "activated": 250, "canceled": 0 } }, "balance": { "points": 100, "pending_points": 50 }, "next_expiration": null, "next_activation": { "points": 50, "type": "PERIOD_BASED", "date": "2026-07-20" }, "object": "card" }, "object": "member_card" } ] } } } } } }, "404": { "description": "Resource not found. Returns `Cannot find member with id ` even if the program ID is incorrect, but the member ID is correct.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "Member not found": { "value": { "code": 404, "key": "not_found", "message": "Resource not found", "details": "Cannot find member with id lmbr_128f962dbc8c4ba5d", "request_id": "v-12bdef050f2cb1ef71", "resource_id": "lmbr_128f962dbc8c4ba5d", "resource_type": "member" } } } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "put": { "operationId": "updateProgramMember", "tags": [ "Programs" ], "summary": "Update program member", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nUpdates a program member's metadata. Provided object keys are merged into the existing metadata; omitted keys are preserved. Pass `metadata: null` to clear all metadata (sets it to an empty object).\n\nThis endpoint cannot change `status`. Use [Activate a program member](/api-reference/programs/activate-a-program-member) or [Deactivate a program member](/api-reference/programs/deactivate-a-program-member) for status transitions.\n\nRecords a `vl.member.updated` activity. Returns the updated member without the `cards` array. Returns `404` when the program or member does not exist. Returns `400` when the request body fails validation or the project `vl_member` metadata schema rejects the payload.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MemberUpdateRequest" } } } }, "responses": { "200": { "description": "The updated member (without cards).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Member" }, "examples": { "Updated member metadata": { "value": { "id": "lmbr_128f962dbc8c4ba5dc", "customer_id": "cust_6onRrs4kCnvSVrTs5YtDPFBG", "program_id": "lprg_128f58429f4c4bf7b2", "status": "ACTIVE", "metadata": { "tier_note": "gold", "source": "crm" }, "created_at": "2026-06-11T15:59:41.298Z", "updated_at": "2026-07-30T10:15:22.401Z", "object": "member" } } } } } }, "400": { "description": "Validation error - request body failed validation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "Member not found": { "value": { "code": 404, "key": "not_found", "message": "Resource not found", "details": "Cannot find member with id lmbr_128f92dbc8c4ba5dc", "request_id": "v-12cf8bce66569748e7", "resource_id": "lmbr_128f92dbc8c4ba5dc", "resource_type": "member" } }, "Program not found": { "value": { "code": 404, "key": "not_found", "message": "Resource not found", "details": "Cannot find program with id lprg_12858429f4c4bf7b2", "request_id": "v-12cf8b960f5adeeb76", "resource_id": "lprg_12858429f4c4bf7b2", "resource_type": "program" } } } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "operationId": "deleteProgramMember", "tags": [ "Programs" ], "summary": "Delete a program member", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nDeletes the member from the program (soft delete - status becomes `DELETED`) and\ndeletes the member's cards. Records a `vl.member.deleted` activity. Returns the\ndeleted member (without cards). Returns 404 when the program or member does not\nexist.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The deleted member.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Member" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/activate": { "post": { "operationId": "activateProgramMember", "tags": [ "Programs" ], "summary": "Activate a program member", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves the member to `ACTIVE` status and records a `vl.member.activated` activity.\nNo request body. Returns 404 when the program or member does not exist. Returns 400\n(`invalid_state_transition`) when the member cannot be activated from its current\nstate.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The activated member (without cards).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Member" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/deactivate": { "post": { "operationId": "deactivateProgramMember", "tags": [ "Programs" ], "summary": "Deactivate a program member", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves the member to `INACTIVE` status and records a `vl.member.deactivated`\nactivity. No request body. Returns 404 when the program or member does not exist.\nReturns 400 (`invalid_state_transition`) when the member cannot be deactivated from\nits current state.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The deactivated member (without cards).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Member" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/activities": { "get": { "operationId": "listProgramMemberActivities", "tags": [ "Programs" ], "summary": "List member activities", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of activities recorded for the member (created,\ndeleted, activated, deactivated, card assigned, card unassigned). Results can be\nfiltered by id, type and created_at. Returns 404 when the program or member does\nnot exist.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of activities to return. Must be between 1 and 100. Defaults to 10 when not provided.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Field(s) to order results by. Valid orders are `created_at` and `-created_at`;\ndefaults to `-created_at`. Accepts a single value or an array of values\n(unrecognized values in the array form are ignored and the default order\napplies). Ordering by the same field in both directions simultaneously is\nrejected.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string" } }, { "type": "string", "enum": [ "created_at", "-created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.\nMust match the pattern `^lcrsambr_[a-f0-9]+$`.", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsambr_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field-specific filter conditions, passed as a deep object, e.g.\n`filters[type][conditions][$is]=vl.member.created`. See the\n`MemberActivityListFilters` schema for available fields and conditions.", "schema": { "oneOf": [ { "$ref": "#/components/schemas/MemberActivityListFilters" }, { "type": "null" } ] } } ], "responses": { "200": { "description": "Cursor-paginated list of member activities.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MemberActivityListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/cards/{cardId}/points": { "post": { "operationId": "adjustCardPoints", "tags": [ "Programs" ], "summary": "Add or subtract card points", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nManually adjusts the points balance of the member's card. A positive `points` value\ncreates an `ADMIN_CREDIT` card transaction (points addition - the added points get\nan expiration date calculated from the card definition's points expiration\nsettings); a negative value creates an `ADMIN_DEBIT` card transaction (points\nsubtraction). When `points` is `0`, no transaction is created and the result status\nis `NO_CHANGE`.\n\nThe transaction is created with status `PENDING` and processed asynchronously.\nBoth the program and the member must be in `ACTIVE` status (423 otherwise). Returns\n404 when the program, member or card does not exist.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "cardId", "in": "path", "required": true, "description": "Loyalty card ID (format `lcrd_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardPointsRequest" } } } }, "responses": { "200": { "description": "Result of the points adjustment.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardPointsAdjustmentResult" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/cards/{cardId}/activities": { "get": { "operationId": "listCardActivities", "tags": [ "Programs" ], "summary": "List card activities", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of activities recorded for the member's card\n(created, assigned, unassigned, code generation succeeded/failed). Results can be\nfiltered by id, type and created_at. Returns 404 when the program, member or card\ndoes not exist.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "cardId", "in": "path", "required": true, "description": "Loyalty card ID (format `lcrd_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of activities to return. Must be between 1 and 100. Defaults to 10 when not provided.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Field(s) to order results by. Valid orders are `created_at` and `-created_at`;\ndefaults to `-created_at`. Accepts a single value or an array of values\n(unrecognized values in the array form are ignored and the default order\napplies). Ordering by the same field in both directions simultaneously is\nrejected.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string" } }, { "type": "string", "enum": [ "created_at", "-created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.\nMust match the pattern `^lcrsacrd_[a-f0-9]+$`.", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsacrd_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field-specific filter conditions, passed as a deep object, e.g.\n`filters[type][conditions][$is]=vl.card.created`. See the\n`CardActivityListFilters` schema for available fields and conditions.", "schema": { "oneOf": [ { "$ref": "#/components/schemas/CardActivityListFilters" }, { "type": "null" } ] } } ], "responses": { "200": { "description": "Cursor-paginated list of card activities.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardActivityListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/cards/{cardId}/pending-points": { "get": { "operationId": "listCardPendingPoints", "tags": [ "Programs" ], "summary": "List card pending points buckets", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of pending points buckets of the member's card.\nPending points are earned points waiting for activation (period-based, fixed-dates\nor event-based activation, per the card definition's pending points settings).\nResults can be ordered by activation `date`. Returns 404 when the program, member\nor card does not exist.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "cardId", "in": "path", "required": true, "description": "Loyalty card ID (format `lcrd_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of buckets to return. Must be between 1 and 100. Defaults to 10 when not provided.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Field(s) to order results by. Valid orders are `date` and `-date`; defaults to\n`date` (soonest activation first). Ordering by the same field in both\ndirections simultaneously is rejected.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "date", "-date" ] } }, { "type": "string", "enum": [ "date", "-date" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.\nMust match the pattern `^lcrscppb_[a-f0-9]+$`.", "schema": { "type": [ "string", "null" ], "pattern": "^lcrscppb_[a-f0-9]+$" } } ], "responses": { "200": { "description": "Cursor-paginated list of pending points buckets.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardPendingPointsBucketListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/cards/{cardId}/pending-points/{bucketId}/activate": { "post": { "operationId": "activateCardPendingPointsBucket", "tags": [ "Programs" ], "summary": "Activate a pending points bucket", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nManually activates a pending points bucket before its scheduled activation date,\ncreating a `PENDING_POINTS_ACTIVATED` card transaction (status `PENDING`, processed\nasynchronously). No request body.\n\nThe program and member must be in `ACTIVE` status, the card definition must have\npending points enabled, the bucket must be in `PENDING` status, and the bucket's\nactivation date must be in the future (423 otherwise). Returns 404 when the\nprogram, member, card or bucket does not exist.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "cardId", "in": "path", "required": true, "description": "Loyalty card ID (format `lcrd_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" } }, { "name": "bucketId", "in": "path", "required": true, "description": "Pending points bucket ID (format `lcppb_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lcppb_[a-f0-9]+$" } } ], "responses": { "200": { "description": "Result of the pending points activation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardPendingPointsActivationResult" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/cards/{cardId}/pending-points/{bucketId}/cancel": { "post": { "operationId": "cancelCardPendingPointsBucket", "tags": [ "Programs" ], "summary": "Cancel a pending points bucket", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nCancels a pending points bucket so its points are never activated, creating a\n`PENDING_POINTS_CANCELED` card transaction (status `PENDING`, processed\nasynchronously). No request body.\n\nThe program and member must be in `ACTIVE` status, the card definition must have\npending points enabled, the bucket must be in `PENDING` status, and the bucket's\nactivation date must be in the future (423 otherwise). Returns 404 when the\nprogram, member, card or bucket does not exist.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "cardId", "in": "path", "required": true, "description": "Loyalty card ID (format `lcrd_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" } }, { "name": "bucketId", "in": "path", "required": true, "description": "Pending points bucket ID (format `lcppb_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lcppb_[a-f0-9]+$" } } ], "responses": { "200": { "description": "Result of the pending points cancellation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardPendingPointsCancellationResult" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/cards/{cardId}/expiring-points": { "get": { "operationId": "listCardExpiringPoints", "tags": [ "Programs" ], "summary": "List card expiring points buckets", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of points expiration buckets of the member's card.\nEach bucket groups active points sharing the same expiration date and expiration\ntype. Results can be ordered by `expiration_date`. Returns 404 when the program,\nmember or card does not exist.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "cardId", "in": "path", "required": true, "description": "Loyalty card ID (format `lcrd_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of buckets to return. Must be between 1 and 100. Defaults to 10 when not provided.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Field(s) to order results by. Valid orders are `expiration_date` and\n`-expiration_date`; defaults to `expiration_date` (soonest expiration first).\nOrdering by the same field in both directions simultaneously is rejected.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "expiration_date", "-expiration_date" ] } }, { "type": "string", "enum": [ "expiration_date", "-expiration_date" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.\nMust match the pattern `^lcrspeb_[a-f0-9]+$`.", "schema": { "type": [ "string", "null" ], "pattern": "^lcrspeb_[a-f0-9]+$" } } ], "responses": { "200": { "description": "Cursor-paginated list of points expiration buckets.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardPointsBucketListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/cards/{cardId}/expiring-points/{bucketId}/expire": { "post": { "operationId": "expireCardPointsBucket", "tags": [ "Programs" ], "summary": "Expire a points bucket", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nManually expires a points bucket before its scheduled expiration date, creating an\n`ADMIN_POINTS_EXPIRATION` card transaction (status `PENDING`, processed\nasynchronously). No request body.\n\nThe program and member must be in `ACTIVE` status, the card definition must have\npoints expiration enabled, the bucket must be in `ACTIVE` status, and the bucket's\nexpiration date must not be in the past (423 otherwise). Returns 404 when the\nprogram, member, card or bucket does not exist.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "cardId", "in": "path", "required": true, "description": "Loyalty card ID (format `lcrd_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" } }, { "name": "bucketId", "in": "path", "required": true, "description": "Points expiration bucket ID (format `lcpeb_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lcpeb_[a-f0-9]+$" } } ], "responses": { "200": { "description": "Result of the points expiration.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardPointsExpirationResult" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/cards/{cardId}/transactions": { "get": { "operationId": "listCardTransactions", "tags": [ "Programs" ], "summary": "List card transactions", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of transactions of the member's card. Results can\nbe filtered by id and created_at, and ordered by `created_at` (default\n`-created_at`, newest first). Returns 404 when the program, member or card does not\nexist.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Loyalty program ID (format `lprg_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "cardId", "in": "path", "required": true, "description": "Loyalty card ID (format `lcrd_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of transactions to return. Must be between 1 and 100. Defaults to 10 when not provided.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Field(s) to order results by. Valid orders are `-created_at` and `created_at`;\ndefaults to `-created_at`. Ordering by the same field in both directions\nsimultaneously is rejected.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at" ] } }, { "type": "string", "enum": [ "-created_at", "created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.\nMust match the pattern `^lcrsctx_[a-f0-9]+$`.", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsctx_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field-specific filter conditions, passed as a deep object, e.g.\n`filters[id][conditions][$is]=lctx_0f5d0a8878caa3ee5c`. See the\n`CardTransactionListFilters` schema for available fields and conditions.", "schema": { "oneOf": [ { "$ref": "#/components/schemas/CardTransactionListFilters" }, { "type": "null" } ] } } ], "responses": { "200": { "description": "Cursor-paginated list of card transactions.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardTransactionListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/rewards/purchases/{rewardTransactionId}/refund": { "post": { "operationId": "refundRewardPurchase", "tags": [ "Programs" ], "summary": "Refund a reward purchase", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nRefunds a previously approved reward purchase transaction. Creates a REFUND-type reward\ntransaction and schedules the return of the spent points to the member's card\n(\"Reward refund transaction created. Points will be returned to the member's card shortly.\").\n\nThe refunded purchase transaction must be of type `PURCHASE` and in `APPROVED` status,\notherwise the request is rejected with a conflict error.\n\nThe request body is optional (an empty payload is allowed). When omitted, default\npolicies are applied: `refund: DEFAULT`, `stock: DEFAULT`.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique loyalty program identifier (format: `lprg_` followed by hexadecimal characters).", "schema": { "type": "string" } }, { "name": "rewardTransactionId", "in": "path", "required": true, "description": "Unique reward transaction identifier of the purchase to refund (format: `lrtx_` followed by hexadecimal characters).", "schema": { "type": "string" } } ], "requestBody": { "required": false, "description": "Optional refund policies. An empty payload is allowed.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardPurchaseRefundRequest" } } } }, "responses": { "202": { "description": "Refund accepted. The refund reward transaction has been created with status APPROVED and points will be returned to the member's card asynchronously.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardPurchaseRefundResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/rewards/purchases": { "get": { "operationId": "listMemberRewardPurchases", "tags": [ "Programs" ], "summary": "List member reward purchases", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nLists reward transactions of type `PURCHASE` for the given program member,\nwith cursor-based pagination. Supports filtering by transaction id, reward id\nand creation date.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique loyalty program identifier (format: `lprg_` followed by hexadecimal characters).", "schema": { "type": "string" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items to return. An integer between 1 and 100; numeric strings are also accepted. Defaults to 10.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sort order. A field name, optionally prefixed with `-` for descending order. May be provided multiple times (array). The same field cannot be used in both ascending and descending order at once. Default: `-created_at`.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at" ] } }, { "type": "string", "enum": [ "-created_at", "created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response (format: `lcrstrx_` followed by hexadecimal characters).", "schema": { "type": [ "string", "null" ], "pattern": "^lcrstrx_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field filters, e.g. `filters[reward_id][conditions][$is]=lrew_...`. Each field accepts a `conditions` object with condition operators.", "schema": { "$ref": "#/components/schemas/RewardPurchaseListFilters" } } ], "responses": { "200": { "description": "Paginated list of reward purchase transactions.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardPurchaseListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "operationId": "purchaseMemberReward", "tags": [ "Programs" ], "summary": "Purchase a reward with points", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nPurchases a reward on behalf of the program member, spending points from the member's\nloyalty card (the card is resolved from the reward cost's card definition).\n\nRequires an ACTIVE program, an ACTIVE member, an ACTIVE reward assigned to the program\nwith available stock, a matching reward cost for the customer's context, and sufficient\npoints within the configured spending limits.\n\nModes:\n- `TRANSACTION` (default) — creates a PENDING reward transaction (and an underlying card\n transaction) processed asynchronously. Returns HTTP 202.\n- `DRY_RUN` — simulates the purchase without creating any transaction. Returns HTTP 200\n with a SIMULATED transaction payload.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique loyalty program identifier (format: `lprg_` followed by hexadecimal characters).", "schema": { "type": "string" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardPurchaseCreateRequest" } } } }, "responses": { "200": { "description": "Dry run result (mode `DRY_RUN`). No transaction was created; the returned transaction has status SIMULATED and no `id`.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardPurchaseCreateResponse" } } } }, "202": { "description": "Purchase accepted (mode `TRANSACTION`). A PENDING reward transaction was created and will be processed asynchronously.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardPurchaseCreateResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/orders/payments": { "get": { "operationId": "listMemberOrderPayments", "tags": [ "Programs" ], "summary": "List member order payments", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nLists order transactions (pay-with-points payments) for the given program member,\nwith cursor-based pagination. Supports filtering by transaction id and creation date.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique loyalty program identifier (format: `lprg_` followed by hexadecimal characters).", "schema": { "type": "string" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items to return. An integer between 1 and 100; numeric strings are also accepted. Defaults to 10.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sort order. A field name, optionally prefixed with `-` for descending order. May be provided multiple times (array). The same field cannot be used in both ascending and descending order at once. Default: `-created_at`.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at" ] } }, { "type": "string", "enum": [ "-created_at", "created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response (format: `lcrsotx_` followed by hexadecimal characters).", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsotx_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field filters, e.g. `filters[id][conditions][$is]=lotx_...`. Each field accepts a `conditions` object with condition operators.", "schema": { "$ref": "#/components/schemas/OrderPaymentListFilters" } } ], "responses": { "200": { "description": "Paginated list of order payment transactions.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrderPaymentListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "operationId": "createMemberOrderPayment", "tags": [ "Programs" ], "summary": "Pay for an order with points", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nPays for an order using points from the specified member loyalty card. The payment amount\nand points to spend are calculated from the card definition's pay-with-points exchange\nratio formula, capped by the card balance and the optional `payment_limit`.\n\nRequires an ACTIVE program, an ACTIVE member, and a card definition with pay-with-points\nenabled and a configured exchange ratio formula.\n\nModes:\n- `TRANSACTION` (default) — creates a PENDING order transaction (and an underlying card\n transaction) processed asynchronously. Returns HTTP 202.\n- `DRY_RUN` — simulates the payment without creating any transaction. Returns HTTP 200\n with a SIMULATED transaction payload.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique loyalty program identifier (format: `lprg_` followed by hexadecimal characters).", "schema": { "type": "string" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrderPaymentCreateRequest" } } } }, "responses": { "200": { "description": "Dry run result (mode `DRY_RUN`). No transaction was created; the returned transaction has status SIMULATED and no `id`.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrderPaymentCreateResponse" } } } }, "202": { "description": "Payment accepted (mode `TRANSACTION`). A PENDING order transaction was created and will be processed asynchronously.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrderPaymentCreateResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/benefits/transactions": { "get": { "operationId": "listMemberBenefitTransactions", "tags": [ "Programs" ], "summary": "List member benefit transactions", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nLists benefit transactions (benefit fulfillments) for the given program member,\nwith cursor-based pagination. Supports filtering by benefit id and creation date.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique loyalty program identifier (format: `lprg_` followed by hexadecimal characters).", "schema": { "type": "string" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items to return. An integer between 1 and 100; numeric strings are also accepted. Defaults to 10.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sort order. A field name, optionally prefixed with `-` for descending order. May be provided multiple times (array). The same field cannot be used in both ascending and descending order at once. Default: `-created_at`.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at" ] } }, { "type": "string", "enum": [ "-created_at", "created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response (format: `lcrsbtx_` followed by hexadecimal characters).", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsbtx_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field filters, e.g. `filters[benefit_id][conditions][$is]=lben_...`. Each field accepts a `conditions` object with condition operators.", "schema": { "$ref": "#/components/schemas/BenefitTransactionListFilters" } } ], "responses": { "200": { "description": "Paginated list of benefit transactions.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BenefitTransactionListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/tiers/transactions": { "get": { "operationId": "listMemberTierTransactions", "tags": [ "Programs" ], "summary": "List member tier transactions", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nLists tier transactions (tier joins, upgrades, downgrades, prolongations and exits)\nfor the given program member, with cursor-based pagination. Supports filtering by\ncard id and creation date.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique loyalty program identifier (format: `lprg_` followed by hexadecimal characters).", "schema": { "type": "string" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items to return. An integer between 1 and 100; numeric strings are also accepted. Defaults to 10.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sort order. A field name, optionally prefixed with `-` for descending order. May be provided multiple times (array). The same field cannot be used in both ascending and descending order at once. Default: `-created_at`.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at" ] } }, { "type": "string", "enum": [ "-created_at", "created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response (format: `lcrsttx_` followed by hexadecimal characters).", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsttx_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field filters, e.g. `filters[card_id][conditions][$is]=lcrd_...`. Each field accepts a `conditions` object with condition operators.", "schema": { "$ref": "#/components/schemas/TierTransactionListFilters" } } ], "responses": { "200": { "description": "Paginated list of tier transactions.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierTransactionListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/members/{memberId}/cards/{cardId}/reports/daily": { "get": { "operationId": "getMemberCardDailyReport", "tags": [ "Programs" ], "summary": "Get card daily points report", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns aggregated daily points statistics for a member's loyalty card over the given\ndate range and resolution.\n\nThe date range is limited per resolution:\nmaximum 90 days for `day`, 12 weeks for `week`, 12 months for `month`, 4 quarters\nfor `quarter`.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique loyalty program identifier (format: `lprg_` followed by hexadecimal characters).", "schema": { "type": "string" } }, { "name": "memberId", "in": "path", "required": true, "description": "Program member ID (format `lmbr_[a-f0-9]+`).", "schema": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" } }, { "name": "cardId", "in": "path", "required": true, "description": "Unique loyalty card identifier (format: `lcrd_` followed by hexadecimal characters).", "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "required": true, "description": "Start of the report date range (inclusive), in `YYYY-MM-DD` format.", "schema": { "type": "string", "format": "date", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" } }, { "name": "end_date", "in": "query", "required": true, "description": "End of the report date range, in `YYYY-MM-DD` format.", "schema": { "type": "string", "format": "date", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" } }, { "name": "resolution", "in": "query", "required": true, "description": "Aggregation resolution of the report. The allowed date range depends on the resolution: `day` — max 90 days, `week` — max 12 weeks, `month` — max 12 months, `quarter` — max 4 quarters.", "schema": { "type": "string", "enum": [ "day", "week", "month", "quarter" ] } } ], "responses": { "200": { "description": "Card daily points report.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardDailyReportResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/reports/spending/daily": { "get": { "operationId": "getProgramSpendingDailyReport", "tags": [ "Programs" ], "summary": "Get program spending daily report", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns aggregated daily points-spending statistics for the program over the given\ndate range and resolution, optionally filtered by card definition.\n\nThe date range is limited per resolution:\nmaximum 90 days for `day`, 12 weeks for `week`, 12 months for `month`, 4 quarters\nfor `quarter`.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique loyalty program identifier (format: `lprg_` followed by hexadecimal characters).", "schema": { "type": "string" } }, { "name": "start_date", "in": "query", "required": true, "description": "Start of the report date range (inclusive), in `YYYY-MM-DD` format.", "schema": { "type": "string", "format": "date", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" } }, { "name": "end_date", "in": "query", "required": true, "description": "End of the report date range, in `YYYY-MM-DD` format.", "schema": { "type": "string", "format": "date", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" } }, { "name": "resolution", "in": "query", "required": true, "description": "Aggregation resolution of the report. The allowed date range depends on the resolution: `day` — max 90 days, `week` — max 12 weeks, `month` — max 12 months, `quarter` — max 4 quarters.", "schema": { "type": "string", "enum": [ "day", "week", "month", "quarter" ] } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field filters, e.g. `filters[card_definition_id][conditions][$is]=lcdef_...`. Each field accepts a `conditions` object with condition operators.", "schema": { "$ref": "#/components/schemas/SpendingReportListFilters" } } ], "responses": { "200": { "description": "Program spending daily report.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SpendingReportDailyResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/programs/{programId}/reports/spending/summary": { "get": { "operationId": "getProgramSpendingSummaryReport", "tags": [ "Programs" ], "summary": "Get program spending summary report", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns total points-spending statistics for the program (all time), optionally\nfiltered by card definition.", "parameters": [ { "name": "programId", "in": "path", "required": true, "description": "Unique loyalty program identifier (format: `lprg_` followed by hexadecimal characters).", "schema": { "type": "string" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field filters, e.g. `filters[card_definition_id][conditions][$is]=lcdef_...`. Each field accepts a `conditions` object with condition operators.", "schema": { "$ref": "#/components/schemas/SpendingReportListFilters" } } ], "responses": { "200": { "description": "Program spending summary report.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SpendingReportSummaryResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/card-definitions": { "get": { "operationId": "listCardDefinitions", "tags": [ "Card Definitions" ], "summary": "List Card Definitions", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of card definitions.\n\nFiltering is supported through the `filters` deep-object query parameter,\ne.g. `filters[name][conditions][$is]=Standard%20Card`.\nThe same field cannot be requested in both ascending and descending\norder at the same time.", "parameters": [ { "name": "limit", "in": "query", "required": false, "description": "Maximum number of card definitions to return. Minimum: 1, maximum: 100. Defaults to 10 when omitted.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sort order. A single field or an array of fields. Prefix a field with `-` for\ndescending order. Defaults to `-created_at`. The same field cannot be used in\nboth ascending and descending direction at the same time.", "schema": { "oneOf": [ { "type": "string", "enum": [ "-name", "name", "-type", "type", "-status", "status", "-created_at", "created_at" ] }, { "type": "array", "items": { "type": "string", "enum": [ "-name", "name", "-type", "type", "-status", "status", "-created_at", "created_at" ] } } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned by a previous call in `cursor.next`. Pattern: `^lcrscdef_[a-f0-9]+$`.", "schema": { "type": "string", "pattern": "^lcrscdef_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Filter conditions per field, e.g. `filters[status][conditions][$is]=ACTIVE`.", "schema": { "$ref": "#/components/schemas/CardDefinitionListFilters" } } ], "responses": { "200": { "description": "A paginated list of card definitions.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardDefinitionListResponse" } } } }, "400": { "description": "Validation error - the request body or query parameters are invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - invalid state transition", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "operationId": "createCardDefinition", "tags": [ "Card Definitions" ], "summary": "Create Card Definition", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nCreates a new card definition. Only `name` and `type` are required; all other\nsections default server-side as follows:\n- `code_config`: 10-character alphanumeric code pattern (`##########`)\n- `points_expiration`: `NO_EXPIRATION`\n- `pending_points`: `IMMEDIATE`\n- `earning_limits`: global `NO_LIMIT`, transactions `NO_LIMIT`\n- `spending_limits`: global `NO_LIMIT`, transactions `NO_LIMIT`\n- `refunds`: spent points `NONE`, earned points `NONE`\n- `balance_settings`: `allow_negative: false`\n- `pay_with_points`: `NO_PAYMENTS`\n\nCross-field rules:\n- `balance_settings.allow_negative` can only be `true` when `points_expiration.type`\n is `NO_EXPIRATION`. Additionally, the earned points refund mode `REVOKE_BELOW_ZERO`\n requires `balance_settings.allow_negative` to be `true`.\n- The earned points refund method `REVOKE_FROM_PENDING` requires\n `pending_points.type` to be one of `PERIOD_BASED`, `FIXED_DATES`, `EVENT_BASED`.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardDefinitionCreateRequest" } } } }, "responses": { "200": { "description": "The created card definition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardDefinition" } } } }, "400": { "description": "Validation error - the request body or query parameters are invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - invalid state transition", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/card-definitions/{cardDefinitionId}": { "get": { "operationId": "getCardDefinition", "tags": [ "Card Definitions" ], "summary": "Get Card Definition", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a single card definition by its ID.", "responses": { "200": { "description": "The card definition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardDefinition" } } } }, "400": { "description": "Validation error - the request body or query parameters are invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - invalid state transition", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique card definition ID. Pattern: `^lcdef_[a-f0-9]+$`.", "schema": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" } } ] }, "put": { "operationId": "updateCardDefinition", "tags": [ "Card Definitions" ], "summary": "Update Card Definition", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nUpdates a card definition. All properties are optional; only provided sections\nare updated. `type` and `status` cannot be changed through this endpoint\n(status transitions are performed via the activate/draft endpoints).\n\nWhen the card definition is in use (e.g. assigned to a program with existing cards),\nupdates to restricted sections may be rejected with a resource-locked error;\nonly `name`, `metadata` and `pay_with_points` are always updatable.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardDefinitionUpdateRequest" } } } }, "responses": { "200": { "description": "The updated card definition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardDefinition" } } } }, "400": { "description": "Validation error - the request body or query parameters are invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - invalid state transition", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique card definition ID. Pattern: `^lcdef_[a-f0-9]+$`.", "schema": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" } } ] }, "delete": { "operationId": "deleteCardDefinition", "tags": [ "Card Definitions" ], "summary": "Delete Card Definition", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nDeletes a card definition. Returns the deleted card definition.", "responses": { "200": { "description": "The deleted card definition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardDefinition" } } } }, "400": { "description": "Validation error - the request body or query parameters are invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - invalid state transition", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique card definition ID. Pattern: `^lcdef_[a-f0-9]+$`.", "schema": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" } } ] } }, "/v2/loyalties/card-definitions/{cardDefinitionId}/activate": { "post": { "operationId": "activateCardDefinition", "tags": [ "Card Definitions" ], "summary": "Activate Card Definition", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nTransitions the card definition from `DRAFT` to `ACTIVE`.\nNo request body. Activating from any other state results in an\ninvalid state transition error (409).", "responses": { "200": { "description": "The activated card definition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardDefinition" } } } }, "400": { "description": "Validation error - the request body or query parameters are invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - invalid state transition", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique card definition ID. Pattern: `^lcdef_[a-f0-9]+$`.", "schema": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" } } ] } }, "/v2/loyalties/card-definitions/{cardDefinitionId}/draft": { "post": { "operationId": "draftCardDefinition", "tags": [ "Card Definitions" ], "summary": "Draft Card Definition", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nTransitions the card definition from `ACTIVE` back to `DRAFT`.\nNo request body. Drafting from any other state results in an\ninvalid state transition error (409).", "responses": { "200": { "description": "The drafted card definition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardDefinition" } } } }, "400": { "description": "Validation error - the request body or query parameters are invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - invalid state transition", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique card definition ID. Pattern: `^lcdef_[a-f0-9]+$`.", "schema": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" } } ] } }, "/v2/loyalties/card-definitions/{cardDefinitionId}/activities": { "get": { "operationId": "listCardDefinitionActivities", "tags": [ "Card Definitions" ], "summary": "List Card Definition Activities", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of activities recorded for the card definition\n(creation, updates, deletion, state transitions and program assignments).\nReturns 404 when the card definition does not exist.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique card definition ID. Pattern: `^lcdef_[a-f0-9]+$`.", "schema": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of activities to return. Minimum: 1, maximum: 100. Defaults to 10 when omitted.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sort order. A single field or an array of fields. Prefix with `-` for descending.\nDefaults to `-created_at`. The same field cannot be used in both ascending and\ndescending direction at the same time.", "schema": { "oneOf": [ { "type": "string", "enum": [ "created_at", "-created_at" ] }, { "type": "array", "items": { "type": "string", "enum": [ "created_at", "-created_at" ] } } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned by a previous call in `cursor.next`. Pattern: `^lcrsacd_[a-f0-9]+$`.", "schema": { "type": "string", "pattern": "^lcrsacd_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Filter conditions per field, e.g. `filters[type][conditions][$is]=vl.card_definition.created`.", "schema": { "$ref": "#/components/schemas/CardDefinitionActivityListFilters" } } ], "responses": { "200": { "description": "A paginated list of card definition activities.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CardDefinitionActivityListResponse" } } } }, "400": { "description": "Validation error - the request body or query parameters are invalid.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - invalid state transition", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/earning-rules": { "post": { "tags": [ "Earning Rules" ], "operationId": "createEarningRule", "summary": "Create earning rule", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nCreates a new earning rule. When `status` is omitted the rule is created as `DRAFT`.\nWhen `validity_hours` is omitted it defaults to `{ \"type\": \"ANY_TIME\" }`.\nWhen `trigger_limits` is omitted it defaults to\n`{ \"cooldown\": { \"type\": \"NO_COOLDOWN\" }, \"frequency\": { \"type\": \"NO_LIMIT\" } }`.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EarningRuleCreateRequest" } } } }, "responses": { "200": { "description": "Earning rule created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EarningRuleResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "get": { "tags": [ "Earning Rules" ], "operationId": "listEarningRules", "summary": "List earning rules", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of earning rules. The same field cannot be used\nin both ascending and descending order at once\n(e.g. `order=name&order=-name` is rejected). Default order is `-created_at`;\n`id` is always appended as a tie-breaker.", "parameters": [ { "name": "limit", "in": "query", "required": false, "description": "Number of items to return. Between 1 and 100, defaults to 10.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sort order. A single value or repeated parameter with multiple values. Prefix with `-` for descending. Allowed values: `-created_at`, `created_at`, `name`, `-name`. Defaults to `-created_at`.", "explode": true, "schema": { "oneOf": [ { "type": "string", "enum": [ "-created_at", "created_at", "name", "-name" ] }, { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at", "name", "-name" ] } } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in `cursor.next` of a previous response. Must match the pattern `^lcrsern_[a-f0-9]+$`.", "schema": { "type": "string", "pattern": "^lcrsern_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Filters as a deep object, e.g. `filters[status][conditions][$is]=ACTIVE` or `filters[name][conditions][$contains]=welcome`. See the schema for allowed fields and conditions.", "schema": { "$ref": "#/components/schemas/EarningRuleListFilters" } } ], "responses": { "200": { "description": "Paginated list of earning rules", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EarningRuleListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/earning-rules/{earningRuleId}": { "get": { "tags": [ "Earning Rules" ], "operationId": "getEarningRule", "summary": "Get earning rule", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a single earning rule by its ID.", "responses": { "200": { "description": "Earning rule", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EarningRuleResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Earning rule ID.", "schema": { "type": "string", "pattern": "^lern_[a-f0-9]+$" } } ] }, "put": { "tags": [ "Earning Rules" ], "operationId": "updateEarningRule", "summary": "Update earning rule", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nUpdates an earning rule. All properties are optional; `status` cannot be changed\nthrough this endpoint (use the activate/deactivate/draft endpoints). For rules that\nare not in `DRAFT` status, only the following properties may effectively change:\nname, earnings, error, validity_hours, start_date, end_date, trigger_limits, metadata.\nEarnings items may carry an `id` (`lernei_...`) to update an existing earning item;\nitems without an `id` are created.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EarningRuleUpdateRequest" } } } }, "responses": { "200": { "description": "Updated earning rule", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EarningRuleResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Earning rule ID.", "schema": { "type": "string", "pattern": "^lern_[a-f0-9]+$" } } ] }, "delete": { "tags": [ "Earning Rules" ], "operationId": "deleteEarningRule", "summary": "Delete earning rule", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nSoft-deletes an earning rule and returns its last state.", "responses": { "200": { "description": "Deleted earning rule", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EarningRuleResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Earning rule ID.", "schema": { "type": "string", "pattern": "^lern_[a-f0-9]+$" } } ] } }, "/v2/loyalties/earning-rules/{earningRuleId}/activate": { "post": { "tags": [ "Earning Rules" ], "operationId": "activateEarningRule", "summary": "Activate earning rule", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves the earning rule to `ACTIVE` status. No request body.\nAllowed transitions: `DRAFT -> ACTIVE`, `INACTIVE -> ACTIVE`.\nInvalid transitions are rejected with a conflict error.", "responses": { "200": { "description": "Activated earning rule", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EarningRuleResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Earning rule ID.", "schema": { "type": "string", "pattern": "^lern_[a-f0-9]+$" } } ] } }, "/v2/loyalties/earning-rules/{earningRuleId}/deactivate": { "post": { "tags": [ "Earning Rules" ], "operationId": "deactivateEarningRule", "summary": "Deactivate earning rule", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves the earning rule to `INACTIVE` status. No request body.\nAllowed transition: `ACTIVE -> INACTIVE`.\nInvalid transitions are rejected with a conflict error.", "responses": { "200": { "description": "Deactivated earning rule", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EarningRuleResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Earning rule ID.", "schema": { "type": "string", "pattern": "^lern_[a-f0-9]+$" } } ] } }, "/v2/loyalties/earning-rules/{earningRuleId}/draft": { "post": { "tags": [ "Earning Rules" ], "operationId": "draftEarningRule", "summary": "Move earning rule to draft", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves the earning rule back to `DRAFT` status. No request body.\nAllowed transition: `ACTIVE -> DRAFT`.\nInvalid transitions are rejected with a conflict error.", "responses": { "200": { "description": "Drafted earning rule", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EarningRuleResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Earning rule ID.", "schema": { "type": "string", "pattern": "^lern_[a-f0-9]+$" } } ] } }, "/v2/loyalties/earning-rules/{earningRuleId}/activities": { "get": { "tags": [ "Earning Rules" ], "operationId": "listEarningRuleActivities", "summary": "List earning rule activities", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of activities (audit trail) for a single earning rule.\nThe same field cannot be used in both ascending and descending order at once.\nDefault order is `-created_at`.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Earning rule ID.", "schema": { "type": "string", "pattern": "^lern_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Number of items to return. Between 1 and 100, defaults to 10.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sort order. A single value or repeated parameter. Allowed values: `created_at`, `-created_at`. Defaults to `-created_at`.", "explode": true, "schema": { "oneOf": [ { "type": "string", "enum": [ "created_at", "-created_at" ] }, { "type": "array", "items": { "type": "string", "enum": [ "created_at", "-created_at" ] } } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in `cursor.next` of a previous response. Must match the pattern `^lcrsaer_[a-f0-9]+$`.", "schema": { "type": "string", "pattern": "^lcrsaer_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Filters as a deep object, e.g. `filters[type][conditions][$is]=vl.earning_rule.updated`.", "schema": { "$ref": "#/components/schemas/EarningRuleActivitiesListFilters" } } ], "responses": { "200": { "description": "Paginated list of earning rule activities", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EarningRuleActivitiesListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/tier-structures": { "post": { "operationId": "createTierStructure", "tags": [ "Tier Structures" ], "summary": "Create tier structure", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nCreates a new tier structure. Depending on `type`, either\n`point_balance` (for `POINT_BALANCE`) or `point_earned` (for `POINT_EARNED`)\nis required and the other must be null/omitted. If `expiration` is omitted it\ndefaults to `{ \"type\": \"NO_EXPIRATION\" }`; if `downgrade` is omitted it defaults\nto `{ \"type\": \"NO_DOWNGRADE\" }`; if `status` is omitted it defaults to `DRAFT`.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierStructureCreateRequest" } } } }, "responses": { "200": { "description": "The created tier structure.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierStructure" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "get": { "operationId": "listTierStructures", "tags": [ "Tier Structures" ], "summary": "List tier structures", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of tier structures. The same field cannot be\nrequested in both ascending and descending order at once. Default order is\n`-created_at`.", "parameters": [ { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items returned per page. An integer between 1 and 100.\nDefaults to 10.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sort order. A single field name or an array of field names; prefix a field with\n`-` for descending order. Default is `-created_at`. The same field must not be\nrequested in both ascending and descending direction at once.", "schema": { "oneOf": [ { "type": "string", "enum": [ "-created_at", "created_at", "name", "-name", "type", "-type", "status", "-status" ] }, { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at", "name", "-name", "type", "-type", "status", "-status" ] } } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.\nMust match the tier structures cursor id format.", "schema": { "type": "string", "pattern": "^lcrsts_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field-specific filter conditions, passed as a deep object\n(e.g. `filters[status][conditions][$is]=ACTIVE`).", "schema": { "$ref": "#/components/schemas/TierStructureListFilters" } } ], "responses": { "200": { "description": "Paginated list of tier structures.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierStructureListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/tier-structures/{tierStructureId}": { "get": { "operationId": "getTierStructure", "tags": [ "Tier Structures" ], "summary": "Get tier structure", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a single tier structure by its id.", "responses": { "200": { "description": "The tier structure.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierStructure" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique tier structure identifier.", "schema": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } } ] }, "put": { "operationId": "updateTierStructure", "tags": [ "Tier Structures" ], "summary": "Update tier structure", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nUpdates a tier structure. All properties are optional; provided\nvalues are merged with the existing tier structure. When `type` is provided as\n`POINT_EARNED`, `point_earned` is required and `point_balance` must be null; when\n`type` is `POINT_BALANCE`, `point_balance` is required and `point_earned` must be null.\nWhen the tier structure is not in `DRAFT` status, only `name` and `metadata` may be\nupdated; attempting to update other properties results in a validation error.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierStructureUpdateRequest" } } } }, "responses": { "200": { "description": "The updated tier structure.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierStructure" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique tier structure identifier.", "schema": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } } ] }, "delete": { "operationId": "deleteTierStructure", "tags": [ "Tier Structures" ], "summary": "Delete tier structure", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nDeletes a tier structure and returns the deleted resource.", "responses": { "200": { "description": "The deleted tier structure.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierStructure" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique tier structure identifier.", "schema": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } } ] } }, "/v2/loyalties/tier-structures/{tierStructureId}/activate": { "post": { "operationId": "activateTierStructure", "tags": [ "Tier Structures" ], "summary": "Activate tier structure", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves the tier structure to the `ACTIVE` status. Allowed state transitions:\n`DRAFT` -> `ACTIVE` and `INACTIVE` -> `ACTIVE`. No request body.", "responses": { "200": { "description": "The activated tier structure.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierStructure" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique tier structure identifier.", "schema": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } } ] } }, "/v2/loyalties/tier-structures/{tierStructureId}/deactivate": { "post": { "operationId": "deactivateTierStructure", "tags": [ "Tier Structures" ], "summary": "Deactivate tier structure", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves the tier structure to the `INACTIVE` status. Allowed state transition:\n`ACTIVE` -> `INACTIVE`. No request body.", "responses": { "200": { "description": "The deactivated tier structure.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierStructure" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique tier structure identifier.", "schema": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } } ] } }, "/v2/loyalties/tier-structures/{tierStructureId}/draft": { "post": { "operationId": "draftTierStructure", "tags": [ "Tier Structures" ], "summary": "Move tier structure to draft", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves the tier structure back to the `DRAFT` status. Allowed state transition:\n`ACTIVE` -> `DRAFT`. No request body.", "responses": { "200": { "description": "The drafted tier structure.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierStructure" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique tier structure identifier.", "schema": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } } ] } }, "/v2/loyalties/tier-structures/{tierStructureId}/tiers": { "post": { "operationId": "createTier", "tags": [ "Tier Structures" ], "summary": "Create tier", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nCreates a tier within the tier structure. If `downgrade` is omitted it defaults to\n`{ \"type\": \"INHERIT\" }`. A tier structure can hold at most 10 tiers.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierCreateRequest" } } } }, "responses": { "200": { "description": "The created tier.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Tier" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique tier structure identifier.", "schema": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } } ] }, "get": { "operationId": "listTiers", "tags": [ "Tier Structures" ], "summary": "List tiers", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of tiers belonging to the tier structure. This\nendpoint does not support a `filters` parameter. The same field cannot be requested\nin both ascending and descending order at once. Default order is `-created_at`.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique tier structure identifier.", "schema": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items returned per page. An integer between 1 and 100.\nDefaults to 10.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sort order. A single field name or an array of field names; prefix a field with\n`-` for descending order. Default is `-created_at`. The same field must not be\nrequested in both ascending and descending direction at once.", "schema": { "oneOf": [ { "type": "string", "enum": [ "created_at", "-created_at", "name", "-name" ] }, { "type": "array", "items": { "type": "string", "enum": [ "created_at", "-created_at", "name", "-name" ] } } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.\nMust match the tiers cursor id format.", "schema": { "type": "string", "pattern": "^lcrst_[a-f0-9]+$" } } ], "responses": { "200": { "description": "Paginated list of tiers.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/tier-structures/{tierStructureId}/tiers/{tierId}": { "put": { "operationId": "updateTier", "tags": [ "Tier Structures" ], "summary": "Update tier", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nUpdates a tier within the tier structure. All properties are optional. When the\nparent tier structure is not in `DRAFT` status, only `name` and `metadata` may be\nupdated.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierUpdateRequest" } } } }, "responses": { "200": { "description": "The updated tier.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Tier" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique tier structure identifier.", "schema": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } }, { "name": "tierId", "in": "path", "required": true, "description": "Unique tier identifier.", "schema": { "type": "string", "pattern": "^lt_[a-f0-9]+$" } } ] }, "delete": { "operationId": "deleteTier", "tags": [ "Tier Structures" ], "summary": "Delete tier", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nDeletes a tier from the tier structure and returns the deleted resource.", "responses": { "200": { "description": "The deleted tier.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Tier" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique tier structure identifier.", "schema": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } }, { "name": "tierId", "in": "path", "required": true, "description": "Unique tier identifier.", "schema": { "type": "string", "pattern": "^lt_[a-f0-9]+$" } } ] } }, "/v2/loyalties/tier-structures/{tierStructureId}/activities": { "get": { "operationId": "listTierStructureActivities", "tags": [ "Tier Structures" ], "summary": "List tier structure activities", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of activities recorded for the tier structure\n(creation, updates, state transitions, assignments, and nested tier changes).\nThe same field cannot be requested in both ascending and descending order at once.\nDefault order is `-created_at`.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique tier structure identifier.", "schema": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of items returned per page. An integer between 1 and 100.\nDefaults to 10.", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Sort order. A single field name or an array of field names; prefix a field with\n`-` for descending order. Default is `-created_at`. The same field must not be\nrequested in both ascending and descending direction at once.", "schema": { "oneOf": [ { "type": "string", "enum": [ "created_at", "-created_at" ] }, { "type": "array", "items": { "type": "string", "enum": [ "created_at", "-created_at" ] } } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.\nMust match the tier structure activities cursor id format.", "schema": { "type": "string", "pattern": "^lcrsats_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field-specific filter conditions, passed as a deep object\n(e.g. `filters[type][conditions][$is]=vl.tier_structure.created`).", "schema": { "$ref": "#/components/schemas/TierStructureActivityListFilters" } } ], "responses": { "200": { "description": "Paginated list of tier structure activities.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TierStructureActivityListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/benefits": { "get": { "operationId": "listBenefits", "tags": [ "Benefits" ], "summary": "List benefits", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of benefits. Supports filtering by `id`, `name`, `status`,\n`type`, and `created_at`, ordering by `created_at`, `name`, and `type` (prefix with `-` for\ndescending), and cursor-based pagination. Deleted benefits are excluded.\nMultiple filters are combined with the `junction` (`AND` by default).\nThe same field cannot be ordered both ascending and descending at the same time.", "parameters": [ { "name": "limit", "in": "query", "required": false, "description": "Maximum number of benefits to return. An integer between 1 and 100.\nDefaults to 10 when omitted.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Ordering of the results. A single field name or an array of field names; prefix with `-`\nfor descending order. Defaults to `-created_at`. The same field cannot be used in both\nascending and descending order at once.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at", "name", "-name", "-type", "type" ] } }, { "type": "string", "enum": [ "-created_at", "created_at", "name", "-name", "-type", "type" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.\nCursors are bound to the filters and order of the query that produced them.", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsben_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field-specific filter conditions, e.g. `filters[name][conditions][$contains]=gold`.\nConditions of multiple fields are combined with the `junction`.", "schema": { "$ref": "#/components/schemas/BenefitListFilters" } } ], "responses": { "200": { "description": "Cursor-paginated list of benefits", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BenefitListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "operationId": "createBenefit", "tags": [ "Benefits" ], "summary": "Create benefit", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nCreates a new benefit. Exactly one type-specific configuration object (`points`,\n`points_proportional`, `material`, or `digital`) is required, matching the `type`.\nWhen `status` is omitted the benefit is created in `DRAFT` status. When `stock` is\nomitted it defaults to `{ \"type\": \"UNLIMITED\" }`.\n\nReferenced resources are validated: the card definition (for points-based types) must\nexist and - when creating with `status: ACTIVE` - must be ACTIVE (423 `resource_locked`\notherwise); the product/SKU (for `MATERIAL`) and campaign (for `DIGITAL`) must exist,\nand the campaign type must match the digital benefit type (`DISCOUNT_COUPONS` or\n`GIFT_VOUCHERS`). The benefit name must be unique per project (409 `duplicate_found`).", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BenefitCreateRequest" } } } }, "responses": { "200": { "description": "The created benefit", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Benefit" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/benefits/{benefitId}": { "get": { "operationId": "getBenefit", "tags": [ "Benefits" ], "summary": "Get benefit", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a single benefit by its ID.", "responses": { "200": { "description": "The benefit", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Benefit" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique benefit ID, prefixed with `lben_`.", "schema": { "type": "string", "pattern": "^lben_[a-f0-9]+$" } } ] }, "put": { "operationId": "updateBenefit", "tags": [ "Benefits" ], "summary": "Update benefit", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nUpdates a benefit. When the benefit is in `DRAFT` status all properties can be updated.\nWhen the benefit is `ACTIVE`, only `name` and `stock` may be updated (400 `invalid_payload`\notherwise). Referenced resources (card definition, product/SKU, campaign) are validated\nthe same way as on create; a points-based benefit can only reference an ACTIVE card\ndefinition (423 `resource_locked` otherwise). The benefit name must remain unique per\nproject (409 `duplicate_found`).", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BenefitUpdateRequest" } } } }, "responses": { "200": { "description": "The updated benefit", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Benefit" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique benefit ID, prefixed with `lben_`.", "schema": { "type": "string", "pattern": "^lben_[a-f0-9]+$" } } ] }, "delete": { "operationId": "deleteBenefit", "tags": [ "Benefits" ], "summary": "Delete benefit", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nSoft-deletes a benefit and returns the deleted benefit. A benefit that is used by any\nearning rule cannot be deleted (400 `resource_in_use`, with `related_object_ids` and\n`related_object_type: earning_rule` in the error body).", "responses": { "200": { "description": "The deleted benefit", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Benefit" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } }, "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique benefit ID, prefixed with `lben_`.", "schema": { "type": "string", "pattern": "^lben_[a-f0-9]+$" } } ] } }, "/v2/loyalties/benefits/{benefitId}/activate": { "post": { "operationId": "activateBenefit", "tags": [ "Benefits" ], "summary": "Activate benefit", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves a benefit from `DRAFT` to `ACTIVE` status. No request body. Only the\n`DRAFT` -> `ACTIVE` transition is allowed; activating from any other state returns\n400 `invalid_state_transition`. A points-based benefit cannot be activated when its\nconnected card definition does not exist or is not ACTIVE (423 `resource_locked`).", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique benefit ID, prefixed with `lben_`.", "schema": { "type": "string", "pattern": "^lben_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The activated benefit", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Benefit" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/benefits/{benefitId}/draft": { "post": { "operationId": "draftBenefit", "tags": [ "Benefits" ], "summary": "Move benefit to draft", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves a benefit from `ACTIVE` back to `DRAFT` status. No request body. Only the\n`ACTIVE` -> `DRAFT` transition is allowed; drafting from any other state returns\n400 `invalid_state_transition`. A benefit assigned to an active earning rule cannot\nbe moved to draft (423 `resource_locked`, key `connected_active_earning_rule`).", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique benefit ID, prefixed with `lben_`.", "schema": { "type": "string", "pattern": "^lben_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The drafted benefit", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Benefit" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "423": { "description": "Resource locked - a related resource is in a state that prevents this operation.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/benefits/{benefitId}/activities": { "get": { "operationId": "listBenefitActivities", "tags": [ "Benefits" ], "summary": "List benefit activities", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of activities recorded for the benefit (created, updated,\ndeleted, activated, drafted). Returns 404 when the benefit does not exist. Supports\nfiltering by activity `id`, `type`, and `created_at`, ordering by `created_at`\n(default `-created_at`), and cursor-based pagination.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique benefit ID, prefixed with `lben_`.", "schema": { "type": "string", "pattern": "^lben_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of activities to return. An integer between 1 and 100.\nDefaults to 10 when omitted.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Ordering of the results. Defaults to `-created_at`. The same field cannot be used in\nboth ascending and descending order at once.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "created_at", "-created_at" ] } }, { "type": "string", "enum": [ "created_at", "-created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsaben_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field-specific filter conditions, e.g. `filters[type][conditions][$is]=vl.benefit.created`.\nConditions of multiple fields are combined with the `junction`.", "schema": { "$ref": "#/components/schemas/BenefitActivityListFilters" } } ], "responses": { "200": { "description": "Cursor-paginated list of benefit activities", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BenefitActivityListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/rewards": { "get": { "operationId": "listRewards", "tags": [ "Rewards" ], "summary": "List rewards v2", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of rewards. Results can be filtered by id, name,\ntype and created_at, and ordered by created_at or name (ascending or descending).\nThe same field cannot be ordered both ascending and descending at the same time.", "parameters": [ { "name": "limit", "in": "query", "required": false, "description": "Maximum number of rewards to return. Must be between 1 and 100.\nDefaults to 10 when not provided.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Field(s) to order results by. Prefix with `-` for descending order.\nAccepts a single value or an array of values. Defaults to `-created_at`.\nThe same field cannot be used in both ascending and descending order at once.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "-created_at", "created_at", "name", "-name" ] } }, { "type": "string", "enum": [ "-created_at", "created_at", "name", "-name" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.\nMust match the pattern `^lcrsrew_[a-f0-9]+$`.", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsrew_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field-specific filter conditions, passed as a deep object, e.g.\n`filters[name][conditions][$contains]=gift`. See the `RewardListFilters`\nschema for available fields and conditions.", "schema": { "oneOf": [ { "$ref": "#/components/schemas/RewardListFilters" }, { "type": "null" } ] } } ], "responses": { "200": { "description": "Cursor-paginated list of rewards.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "post": { "operationId": "createReward", "tags": [ "Rewards" ], "summary": "Create a reward", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nCreates a new reward. `name`, `type` and `costs` are required. When `type` is\n`MATERIAL` the `material` object is required and `digital` must be null; when\n`type` is `DIGITAL` the `digital` object is required and `material` must be null.\nThe reward can be created directly in `DRAFT` (default) or `ACTIVE` status.\nWhen `validity_hours` is not provided it defaults to `{ \"type\": \"ANY_TIME\" }`.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardCreateRequest" } } } }, "responses": { "200": { "description": "The created reward.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/rewards/{rewardId}": { "get": { "operationId": "getReward", "tags": [ "Rewards" ], "summary": "Get a reward by ID", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a single reward by its ID.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique reward identifier, prefixed with `lrew_`.", "schema": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The reward.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "put": { "operationId": "updateReward", "tags": [ "Rewards" ], "summary": "Update a reward", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nUpdates an existing reward. When `type` is provided as `MATERIAL` the `material`\nobject is required and `digital` must be null; when `type` is provided as `DIGITAL`\nthe `digital` object is required and `material` must be null.\n\nIn `DRAFT` status all properties can be updated. In `ACTIVE`/`INACTIVE` status only\nthe following properties can be updated: `name`, `metadata`, `refunds`,\n`validity_hours`, `start_date`, `end_date`, `costs`.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique reward identifier, prefixed with `lrew_`.", "schema": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardUpdateRequest" } } } }, "responses": { "200": { "description": "The updated reward.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } }, "delete": { "operationId": "deleteReward", "tags": [ "Rewards" ], "summary": "Delete a reward", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nDeletes a reward (moves it to the DELETED status). Returns the deleted reward.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique reward identifier, prefixed with `lrew_`.", "schema": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The deleted reward.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/rewards/{rewardId}/activate": { "post": { "operationId": "activateReward", "tags": [ "Rewards" ], "summary": "Activate a reward", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves the reward to the ACTIVE status. Allowed from DRAFT or INACTIVE status;\nother transitions are rejected with a conflict error. This endpoint takes no\nrequest body.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique reward identifier, prefixed with `lrew_`.", "schema": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The activated reward.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/rewards/{rewardId}/deactivate": { "post": { "operationId": "deactivateReward", "tags": [ "Rewards" ], "summary": "Deactivate a reward", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves the reward to the INACTIVE status. Allowed only from ACTIVE status;\nother transitions are rejected with a conflict error. This endpoint takes no\nrequest body.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique reward identifier, prefixed with `lrew_`.", "schema": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The deactivated reward.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/rewards/{rewardId}/draft": { "post": { "operationId": "draftReward", "tags": [ "Rewards" ], "summary": "Move a reward back to draft", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nMoves the reward back to the DRAFT status. Allowed only from ACTIVE status;\nother transitions are rejected with a conflict error. This endpoint takes no\nrequest body.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique reward identifier, prefixed with `lrew_`.", "schema": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" } } ], "responses": { "200": { "description": "The drafted reward.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/rewards/{rewardId}/activities": { "get": { "operationId": "listRewardActivities", "tags": [ "Rewards" ], "summary": "List reward activities", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nReturns a cursor-paginated list of activities recorded for the given reward\n(created, updated, deleted, assigned, unassigned, activated, deactivated, drafted).\nReturns 404 when the reward does not exist.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Unique reward identifier, prefixed with `lrew_`.", "schema": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" } }, { "name": "limit", "in": "query", "required": false, "description": "Maximum number of activities to return. Must be between 1 and 100.\nDefaults to 10 when not provided.", "schema": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 100, "default": 10 } }, { "name": "order", "in": "query", "required": false, "description": "Field(s) to order results by. Prefix with `-` for descending order.\nAccepts a single value or an array of values. Defaults to `-created_at`.\nThe same field cannot be used in both ascending and descending order at once.", "schema": { "oneOf": [ { "type": "array", "items": { "type": "string", "enum": [ "created_at", "-created_at" ] } }, { "type": "string", "enum": [ "created_at", "-created_at" ] }, { "type": "null" } ] } }, { "name": "cursor", "in": "query", "required": false, "description": "Pagination cursor returned in the `cursor.next` field of a previous response.\nMust match the pattern `^lcrsarew_[a-f0-9]+$`.", "schema": { "type": [ "string", "null" ], "pattern": "^lcrsarew_[a-f0-9]+$" } }, { "name": "filters", "in": "query", "required": false, "style": "deepObject", "explode": true, "description": "Field-specific filter conditions, passed as a deep object, e.g.\n`filters[type][conditions][$is]=vl.reward.created`. See the\n`RewardActivityListFilters` schema for available fields and conditions.", "schema": { "oneOf": [ { "$ref": "#/components/schemas/RewardActivityListFilters" }, { "type": "null" } ] } } ], "responses": { "200": { "description": "Cursor-paginated list of reward activities.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RewardActivityListResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/examine/earning-rules": { "post": { "tags": [ "Examine" ], "operationId": "examineEarningRules", "summary": "Examine earning rules", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nEstimates earning opportunities for a customer without triggering any actual earning.\nThe `trigger` selects whether all trigger events or one specific event is examined.\nWhen a specific event is selected, exactly one matching context object is required:\n`customer_order_paid` for `customer.order.paid`, `customer_segment_entered` for\n`customer.segment.entered`, and `customer_custom_event` for `customer.custom_event`\n(the other context objects must not be present).", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExamineEarningRulesRequest" } } } }, "responses": { "200": { "description": "Earning rules examination result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExamineEarningRulesResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } }, "/v2/loyalties/examine/rewards": { "post": { "tags": [ "Examine" ], "operationId": "examineRewards", "summary": "Examine rewards", "description": "\n\n\nBETA endpoint\n\nThis is a work-in-progress documentation of a BETA endpoint. The parameters, fields, request and response bodies, and other data may subject to change. If you want to share feedback or improvements, contact [Voucherify support](https://www.voucherify.io/contact-support) or your Technical Account Manager.\n\n\n\nEstimates which rewards a customer can obtain across their loyalty program memberships,\nincluding availability status, points cost and unavailability reasons.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExamineRewardsRequest" } } } }, "responses": { "200": { "description": "Rewards examination result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExamineRewardsResponse" } } } }, "400": { "description": "Validation error - request body or query parameters failed validation, or the operation is not allowed in the current resource state.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "404": { "description": "Resource not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "409": { "description": "Conflict - e.g. duplicate resource or invalid state transition.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } }, "500": { "description": "Internal server error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } } } } } } }, "components": { "schemas": { "ErrorResponse": { "type": "object", "description": "Standard error response returned by all Loyalty v2 endpoints.", "properties": { "code": { "type": "integer", "description": "HTTP status code of the error." }, "key": { "type": "string", "description": "Machine-readable error key." }, "message": { "type": "string", "description": "Human-readable error message." }, "details": { "type": "string", "description": "Additional details about the error." }, "request_id": { "type": "string", "description": "Identifier of the request that produced the error." }, "resource_id": { "type": "string", "description": "Identifier of the resource that produced the error." }, "resource_type": { "type": "string", "description": "Type of the resource that produced the error." } } }, "ProgramValidityDailyHoursUpsert": { "type": "object", "description": "A single daily validity-hours window definition.", "properties": { "days_of_week": { "type": "array", "description": "Days of week the window applies to. 0 = Sunday through 6 = Saturday. Items must be unique.", "items": { "type": "integer", "minimum": 0, "maximum": 6 }, "minItems": 1, "maxItems": 7, "uniqueItems": true }, "start_time": { "type": "string", "description": "Window start time in `HH:mm` format. If seconds are provided, they are ignored.", "example": "09:00" }, "end_time": { "type": "string", "description": "Window end time in `HH:mm` format. If seconds are provided, they are ignored.", "example": "17:00" } }, "required": [ "days_of_week", "start_time", "end_time" ], "additionalProperties": false }, "ProgramValidityHoursUpsert": { "type": "object", "description": "Validity hours configuration. When `type` is `ANY_TIME`, `daily` must be omitted or null.\nWhen `type` is `DAILY`, `daily` is required and must contain at least one window.", "properties": { "type": { "type": "string", "description": "Validity hours mode. `ANY_TIME` means the program is always valid; `DAILY` restricts validity to configured daily windows.", "enum": [ "DAILY", "ANY_TIME" ] }, "daily": { "description": "Daily validity windows. Required when `type` is `DAILY`; must be null/omitted when `type` is `ANY_TIME`.", "oneOf": [ { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/ProgramValidityDailyHoursUpsert" } }, { "type": "null" } ] } }, "required": [ "type" ], "additionalProperties": false, "allOf": [ { "if": { "properties": { "type": { "const": "ANY_TIME" } } }, "then": { "properties": { "daily": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "DAILY" } } }, "then": { "required": [ "daily" ], "properties": { "daily": { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/ProgramValidityDailyHoursUpsert" } } } } } ] }, "ProgramCardDefinitionAssignItem": { "type": "object", "description": "Card definition to assign to the program.", "properties": { "id": { "type": "string", "description": "Unique card definition identifier.", "pattern": "^lcdef_[a-f0-9]+$" } }, "required": [ "id" ], "additionalProperties": false }, "ProgramCardDefinitionUnassignItem": { "type": "object", "description": "Card definition to unassign from the program.", "properties": { "id": { "type": "string", "description": "Unique card definition identifier.", "pattern": "^lcdef_[a-f0-9]+$" } }, "required": [ "id" ], "additionalProperties": false }, "ProgramEarningRuleAssignItem": { "type": "object", "description": "Earning rule to assign to the program.", "properties": { "id": { "type": "string", "description": "Unique earning rule identifier.", "pattern": "^lern_[a-f0-9]+$" } }, "required": [ "id" ], "additionalProperties": false }, "ProgramEarningRuleUnassignItem": { "type": "object", "description": "Earning rule to unassign from the program.", "properties": { "id": { "type": "string", "description": "Unique earning rule identifier.", "pattern": "^lern_[a-f0-9]+$" } }, "required": [ "id" ], "additionalProperties": false }, "ProgramTierStructureAssignItem": { "type": "object", "description": "Tier structure to assign to the program.", "properties": { "id": { "type": "string", "description": "Unique tier structure identifier.", "pattern": "^lts_[a-f0-9]+$" } }, "required": [ "id" ], "additionalProperties": false }, "ProgramTierStructureUnassignItem": { "type": "object", "description": "Tier structure to unassign from the program.", "properties": { "id": { "type": "string", "description": "Unique tier structure identifier.", "pattern": "^lts_[a-f0-9]+$" } }, "required": [ "id" ], "additionalProperties": false }, "ProgramRewardAssignmentStockLimited": { "type": "object", "description": "Limited stock configuration.", "properties": { "quantity": { "type": "integer", "description": "Available stock quantity.", "minimum": 0, "maximum": 9007199254740991 } }, "required": [ "quantity" ], "additionalProperties": false }, "ProgramRewardAssignmentStock": { "type": "object", "description": "Reward stock configuration. When `type` is `UNLIMITED`, `limited` must not be provided.\nWhen `type` is `LIMITED`, `limited` is required.", "properties": { "type": { "type": "string", "description": "Stock type.", "enum": [ "UNLIMITED", "LIMITED" ] }, "limited": { "description": "Limited stock details. Required when `type` is `LIMITED`; must not be provided when `type` is `UNLIMITED`.", "oneOf": [ { "$ref": "#/components/schemas/ProgramRewardAssignmentStockLimited" }, { "type": "null" } ] } }, "required": [ "type" ], "additionalProperties": false, "allOf": [ { "if": { "properties": { "type": { "const": "UNLIMITED" } } }, "then": { "not": { "required": [ "limited" ] } } }, { "if": { "properties": { "type": { "const": "LIMITED" } } }, "then": { "required": [ "limited" ], "properties": { "limited": { "$ref": "#/components/schemas/ProgramRewardAssignmentStockLimited" } } } } ] }, "ProgramRewardAssignItem": { "type": "object", "description": "Reward to assign to the program, together with its stock configuration.", "properties": { "id": { "type": "string", "description": "Unique reward identifier.", "pattern": "^lrew_[a-f0-9]+$" }, "stock": { "$ref": "#/components/schemas/ProgramRewardAssignmentStock" } }, "required": [ "id", "stock" ], "additionalProperties": false }, "ProgramRewardUnassignItem": { "type": "object", "description": "Reward to unassign from the program.", "properties": { "id": { "type": "string", "description": "Unique reward identifier.", "pattern": "^lrew_[a-f0-9]+$" } }, "required": [ "id" ], "additionalProperties": false }, "ProgramCreateRequest": { "type": "object", "description": "Payload for creating a loyalty program.", "properties": { "name": { "type": "string", "description": "Program name.", "minLength": 1, "maxLength": 200 }, "start_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Program validity start date, in ISO 8601 date-time format." }, "end_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Program validity end date, in ISO 8601 date-time format." }, "validity_hours": { "description": "Validity hours configuration. Defaults to `ANY_TIME` when omitted.", "oneOf": [ { "$ref": "#/components/schemas/ProgramValidityHoursUpsert" }, { "type": "null" } ] }, "status": { "description": "Initial program status. Only `ACTIVE` and `DRAFT` are allowed at creation. Defaults to `DRAFT`.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, { "type": "null" } ] }, "metadata": { "description": "Arbitrary key-value metadata. Validated against the `vl_program` metadata schema definition of the project. Defaults to `{}`.", "oneOf": [ { "type": "object" }, { "type": "null" } ] }, "card_definitions": { "description": "Card definitions to assign at creation. Required (with active card definitions) when creating the program with status `ACTIVE`.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramCardDefinitionAssignItem" }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] }, "earning_rules": { "description": "Earning rules to assign at creation. Required (with active earning rules) when creating the program with status `ACTIVE`.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramEarningRuleAssignItem" }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] }, "rewards": { "description": "Rewards to assign at creation, each with its stock configuration.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramRewardAssignItem" }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] }, "tier_structures": { "description": "Tier structures to assign at creation. A program can have at most one tier structure.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramTierStructureAssignItem" }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] } }, "required": [ "name" ], "additionalProperties": false }, "ProgramUpdateRequest": { "type": "object", "description": "Payload for updating a loyalty program. All properties are optional. When the program is\nnot in `DRAFT` status, only `name` and `metadata` may be changed.", "properties": { "name": { "type": "string", "description": "Program name.", "minLength": 1, "maxLength": 200 }, "start_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Program validity start date, in ISO 8601 date-time format." }, "end_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Program validity end date, in ISO 8601 date-time format." }, "validity_hours": { "description": "Validity hours configuration.", "oneOf": [ { "$ref": "#/components/schemas/ProgramValidityHoursUpsert" }, { "type": "null" } ] }, "metadata": { "description": "Arbitrary key-value metadata. Validated against the `vl_program` metadata schema definition of the project.", "oneOf": [ { "type": "object" }, { "type": "null" } ] } }, "additionalProperties": false }, "ProgramCardDefinitionBatchRequest": { "type": "object", "description": "Batch of card definition assignment operations. `unassign` operations are processed\nbefore `assign` operations. Duplicate ids within a batch are rejected.", "properties": { "assign": { "description": "Card definitions to assign.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramCardDefinitionAssignItem" }, "maxItems": 10 }, { "type": "null" } ] }, "unassign": { "description": "Card definitions to unassign.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramCardDefinitionUnassignItem" }, "maxItems": 10 }, { "type": "null" } ] } }, "additionalProperties": false }, "ProgramEarningRuleBatchRequest": { "type": "object", "description": "Batch of earning rule assignment operations. `unassign` operations are processed\nbefore `assign` operations. Duplicate ids within a batch are rejected.", "properties": { "assign": { "description": "Earning rules to assign.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramEarningRuleAssignItem" }, "maxItems": 10 }, { "type": "null" } ] }, "unassign": { "description": "Earning rules to unassign.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramEarningRuleUnassignItem" }, "maxItems": 10 }, { "type": "null" } ] } }, "additionalProperties": false }, "ProgramTierStructureBatchRequest": { "type": "object", "description": "Batch of tier structure assignment operations. `unassign` operations are processed\nbefore `assign` operations. Duplicate ids within a batch are rejected.", "properties": { "assign": { "description": "Tier structures to assign.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramTierStructureAssignItem" }, "maxItems": 10 }, { "type": "null" } ] }, "unassign": { "description": "Tier structures to unassign.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramTierStructureUnassignItem" }, "maxItems": 10 }, { "type": "null" } ] } }, "additionalProperties": false }, "ProgramRewardBatchRequest": { "type": "object", "description": "Batch of reward assignment operations. `unassign` operations are processed\nbefore `assign` operations. Duplicate ids within a batch are rejected.", "properties": { "assign": { "description": "Rewards to assign, each with its stock configuration.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramRewardAssignItem" }, "maxItems": 10 }, { "type": "null" } ] }, "unassign": { "description": "Rewards to unassign.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramRewardUnassignItem" }, "maxItems": 10 }, { "type": "null" } ] } }, "additionalProperties": false }, "ProgramRewardAssignmentUpdateRequest": { "type": "object", "description": "Payload for updating the stock configuration of a reward assigned to a program.", "properties": { "stock": { "$ref": "#/components/schemas/ProgramRewardAssignmentStock" } }, "required": [ "stock" ], "minProperties": 1, "additionalProperties": false }, "ProgramValidityDailyHours": { "type": "object", "description": "A single daily validity-hours window.", "properties": { "days_of_week": { "type": "array", "description": "Days of week the window applies to. 0 = Sunday through 6 = Saturday.", "items": { "type": "integer", "minimum": 0, "maximum": 6 } }, "start_time": { "type": "string", "description": "Window start time in `HH:mm` format." }, "end_time": { "type": "string", "description": "Window end time in `HH:mm` format." } } }, "ProgramValidityHours": { "type": "object", "description": "Validity hours configuration of the program.", "properties": { "type": { "type": "string", "description": "Validity hours mode.", "enum": [ "DAILY", "ANY_TIME" ] }, "daily": { "type": "array", "description": "Daily validity windows. Present only when `type` is `DAILY`.", "items": { "$ref": "#/components/schemas/ProgramValidityDailyHours" } } } }, "Program": { "type": "object", "description": "A loyalty program.", "properties": { "id": { "type": "string", "description": "Unique program identifier.", "pattern": "^lprg_[a-f0-9]+$" }, "name": { "type": "string", "description": "Program name." }, "status": { "type": "string", "description": "Program status.", "enum": [ "DRAFT", "ACTIVE", "INACTIVE", "DELETED" ] }, "start_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Program validity start date (ISO 8601), or null when not set." }, "end_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Program validity end date (ISO 8601), or null when not set." }, "validity_hours": { "$ref": "#/components/schemas/ProgramValidityHours", "description": "Validity hours configuration. Defaults to type `ANY_TIME`." }, "metadata": { "type": "object", "description": "Arbitrary key-value metadata. Defaults to `{}`." }, "created_at": { "type": "string", "format": "date-time", "description": "Creation timestamp (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last update timestamp (ISO 8601), or null when never updated." }, "object": { "type": "string", "description": "Object type marker.", "const": "program" } } }, "ProgramCreateAssignedCardDefinition": { "type": "object", "description": "Card definition assigned during program creation.", "properties": { "id": { "type": "string", "description": "Unique card definition identifier.", "pattern": "^lcdef_[a-f0-9]+$" } } }, "ProgramCreateAssignedEarningRule": { "type": "object", "description": "Earning rule assigned during program creation.", "properties": { "id": { "type": "string", "description": "Unique earning rule identifier.", "pattern": "^lern_[a-f0-9]+$" } } }, "ProgramCreateAssignedReward": { "type": "object", "description": "Reward assigned during program creation.", "properties": { "id": { "type": "string", "description": "Unique reward identifier.", "pattern": "^lrew_[a-f0-9]+$" }, "stock": { "$ref": "#/components/schemas/ProgramRewardAssignmentStock", "description": "Stock configuration provided at assignment. Omitted when not provided." } } }, "ProgramCreateAssignedTierStructure": { "type": "object", "description": "Tier structure assigned during program creation.", "properties": { "id": { "type": "string", "description": "Unique tier structure identifier.", "pattern": "^lts_[a-f0-9]+$" } } }, "ProgramCreateResponse": { "description": "Program create response - the program extended with the ids of resources assigned at creation.", "allOf": [ { "$ref": "#/components/schemas/Program" }, { "type": "object", "properties": { "card_definitions": { "description": "Card definitions assigned at creation, or null when none were provided.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramCreateAssignedCardDefinition" } }, { "type": "null" } ] }, "earning_rules": { "description": "Earning rules assigned at creation, or null when none were provided.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramCreateAssignedEarningRule" } }, { "type": "null" } ] }, "rewards": { "description": "Rewards assigned at creation, or null when none were provided.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramCreateAssignedReward" } }, { "type": "null" } ] }, "tier_structures": { "description": "Tier structures assigned at creation, or null when none were provided.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramCreateAssignedTierStructure" } }, { "type": "null" } ] } } } ] }, "ProgramListCursor": { "type": "object", "description": "Cursor for fetching the next page of results. Present only when more results are available.", "properties": { "next": { "type": "string", "description": "Cursor id to pass as the `cursor` query parameter in the next request." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp after which the cursor expires and can no longer be used." } } }, "ProgramListResponse": { "type": "object", "description": "Cursor-paginated list of programs.", "properties": { "object": { "type": "string", "description": "Object type marker.", "const": "list" }, "data": { "type": "array", "description": "Programs on the current page.", "items": { "$ref": "#/components/schemas/Program" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/ProgramListCursor" }, { "type": "null" } ] } } }, "ProgramCardDefinitionAssignment": { "type": "object", "description": "A card definition assigned to a program.", "properties": { "card_type": { "type": "string", "description": "Card type of the assigned card definition.", "enum": [ "INDIVIDUAL" ] }, "card_definition_id": { "type": "string", "description": "Unique card definition identifier.", "pattern": "^lcdef_[a-f0-9]+$" }, "created_at": { "type": "string", "format": "date-time", "description": "Assignment creation timestamp (ISO 8601)." }, "object": { "type": "string", "description": "Object type marker.", "const": "program_card_definition" } } }, "ProgramCardDefinitionAssignmentListResponse": { "type": "object", "description": "Cursor-paginated list of card definition assignments.", "properties": { "object": { "type": "string", "description": "Object type marker.", "const": "list" }, "data": { "type": "array", "description": "Card definition assignments on the current page.", "items": { "$ref": "#/components/schemas/ProgramCardDefinitionAssignment" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/ProgramListCursor" }, { "type": "null" } ] } } }, "ProgramCardDefinitionBatchResponse": { "type": "object", "description": "Result of a card definition assignment batch. Keys are null when the corresponding operation list was not provided.", "properties": { "assigned": { "description": "Assignments created by the batch, or null when no assign operations were requested.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramCardDefinitionAssignment" } }, { "type": "null" } ] }, "unassigned": { "description": "Assignments removed by the batch, or null when no unassign operations were requested.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramCardDefinitionAssignment" } }, { "type": "null" } ] } } }, "ProgramEarningRuleAssignment": { "type": "object", "description": "An earning rule assigned to a program.", "properties": { "earning_rule_id": { "type": "string", "description": "Unique earning rule identifier.", "pattern": "^lern_[a-f0-9]+$" }, "created_at": { "type": "string", "format": "date-time", "description": "Assignment creation timestamp (ISO 8601)." }, "object": { "type": "string", "description": "Object type marker.", "const": "program_earning_rule" } } }, "ProgramEarningRuleAssignmentListResponse": { "type": "object", "description": "Cursor-paginated list of earning rule assignments.", "properties": { "object": { "type": "string", "description": "Object type marker.", "const": "list" }, "data": { "type": "array", "description": "Earning rule assignments on the current page.", "items": { "$ref": "#/components/schemas/ProgramEarningRuleAssignment" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/ProgramListCursor" }, { "type": "null" } ] } } }, "ProgramEarningRuleBatchResponse": { "type": "object", "description": "Result of an earning rule assignment batch. Keys are null when the corresponding operation list was not provided.", "properties": { "assigned": { "description": "Assignments created by the batch, or null when no assign operations were requested.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramEarningRuleAssignment" } }, { "type": "null" } ] }, "unassigned": { "description": "Assignments removed by the batch, or null when no unassign operations were requested.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramEarningRuleAssignment" } }, { "type": "null" } ] } } }, "ProgramTierStructureAssignment": { "type": "object", "description": "A tier structure assigned to a program.", "properties": { "tier_structure_id": { "type": "string", "description": "Unique tier structure identifier.", "pattern": "^lts_[a-f0-9]+$" }, "created_at": { "type": "string", "format": "date-time", "description": "Assignment creation timestamp (ISO 8601)." }, "object": { "type": "string", "description": "Object type marker.", "const": "program_tier_structure" } } }, "ProgramTierStructureAssignmentListResponse": { "type": "object", "description": "Cursor-paginated list of tier structure assignments.", "properties": { "object": { "type": "string", "description": "Object type marker.", "const": "list" }, "data": { "type": "array", "description": "Tier structure assignments on the current page.", "items": { "$ref": "#/components/schemas/ProgramTierStructureAssignment" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/ProgramListCursor" }, { "type": "null" } ] } } }, "ProgramTierStructureBatchResponse": { "type": "object", "description": "Result of a tier structure assignment batch. Keys are null when the corresponding operation list was not provided.", "properties": { "assigned": { "description": "Assignments created by the batch, or null when no assign operations were requested.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramTierStructureAssignment" } }, { "type": "null" } ] }, "unassigned": { "description": "Assignments removed by the batch, or null when no unassign operations were requested.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramTierStructureAssignment" } }, { "type": "null" } ] } } }, "ProgramRewardAssignment": { "type": "object", "description": "A reward assigned to a program, with stock configuration and redemption counter.", "properties": { "reward_id": { "type": "string", "description": "Unique reward identifier.", "pattern": "^lrew_[a-f0-9]+$" }, "stock": { "$ref": "#/components/schemas/ProgramRewardAssignmentStock", "description": "Stock configuration of the assignment." }, "redeemed": { "type": "number", "description": "Number of times the reward has been redeemed within the program. Defaults to 0." }, "created_at": { "type": "string", "format": "date-time", "description": "Assignment creation timestamp (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last update timestamp (ISO 8601), or null when never updated." }, "object": { "type": "string", "description": "Object type marker.", "const": "program_reward" } } }, "ProgramRewardAssignmentListResponse": { "type": "object", "description": "Cursor-paginated list of reward assignments.", "properties": { "object": { "type": "string", "description": "Object type marker.", "const": "list" }, "data": { "type": "array", "description": "Reward assignments on the current page.", "items": { "$ref": "#/components/schemas/ProgramRewardAssignment" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/ProgramListCursor" }, { "type": "null" } ] } } }, "ProgramRewardBatchResponse": { "type": "object", "description": "Result of a reward assignment batch. Keys are null when the corresponding operation list was not provided.", "properties": { "assigned": { "description": "Assignments created by the batch, or null when no assign operations were requested.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramRewardAssignment" } }, { "type": "null" } ] }, "unassigned": { "description": "Assignments removed by the batch, or null when no unassign operations were requested.", "oneOf": [ { "type": "array", "items": { "$ref": "#/components/schemas/ProgramRewardAssignment" } }, { "type": "null" } ] } } }, "ProgramActivitySource": { "type": "object", "description": "Origin of the activity.", "properties": { "channel": { "type": "string", "description": "Channel the activity originated from.", "enum": [ "USER_PORTAL", "API", "CLIENT_API", "INTERNAL" ] }, "user": { "type": "object", "description": "User that triggered the activity. Present for user-originated activities.", "properties": { "id": { "type": "string", "description": "User identifier." } } }, "api_key": { "type": "object", "description": "API key that triggered the activity. Present for API-originated activities.", "properties": { "name": { "type": "string", "description": "API key name." }, "app_id": { "type": "string", "description": "Application id of the API key." }, "client_app_id": { "type": "string", "description": "Client application id of the API key." } } } } }, "ProgramActivity": { "type": "object", "description": "An activity recorded for a program. The `data` payload always contains the `program`\nobject snapshot; assignment activities additionally include the related resource\n(`card_definition`/`earning_rule`/`reward`/`tier_structure`) and the assignment object\n(`program_card_definition`/`program_earning_rule`/`program_reward`/`program_tier_structure`).", "properties": { "id": { "type": "string", "description": "Unique activity identifier.", "pattern": "^laprg_[a-f0-9]+$" }, "program_id": { "type": "string", "description": "Identifier of the program the activity relates to.", "pattern": "^lprg_[a-f0-9]+$" }, "type": { "type": "string", "description": "Activity type.", "enum": [ "vl.program.created", "vl.program.updated", "vl.program.deleted", "vl.program.activated", "vl.program.deactivated", "vl.program.card_definition.assigned", "vl.program.card_definition.unassigned", "vl.program.earning_rule.assigned", "vl.program.earning_rule.unassigned", "vl.program.reward.assigned", "vl.program.reward.unassigned", "vl.program.reward.updated", "vl.program.tier_structure.assigned", "vl.program.tier_structure.unassigned" ] }, "data": { "type": "object", "description": "Activity payload. Always includes a `program` snapshot; assignment activities also include the assigned/unassigned resource and assignment objects." }, "created_at": { "type": "string", "format": "date-time", "description": "Activity timestamp (ISO 8601)." }, "group_id": { "type": "string", "description": "Identifier grouping activities recorded within the same operation." }, "source": { "$ref": "#/components/schemas/ProgramActivitySource", "description": "Origin of the activity. Omitted when unknown." } } }, "ProgramActivityListResponse": { "type": "object", "description": "Cursor-paginated list of program activities.", "properties": { "object": { "type": "string", "description": "Object type marker.", "const": "list" }, "data": { "type": "array", "description": "Activities on the current page.", "items": { "$ref": "#/components/schemas/ProgramActivity" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/ProgramListCursor" }, { "type": "null" } ] } } }, "ProgramIdFilterConditions": { "type": "object", "description": "Filter conditions for the program `id` field (ID field type). Allowed conditions:\n`$is`, `$is_not`, `$in`, `$not_in`. Values must match the program id pattern\n`^lprg_[a-f0-9]+$`. Each condition accepts a single string or an array of strings\n(max 1 item for `$is`/`$is_not`, max 100 items for `$in`/`$not_in`).", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Field equals the given id.", "oneOf": [ { "type": "string", "pattern": "^lprg_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Field does not equal the given id.", "oneOf": [ { "type": "string", "pattern": "^lprg_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Field equals any of the given ids.", "oneOf": [ { "type": "string", "pattern": "^lprg_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Field equals none of the given ids.", "oneOf": [ { "type": "string", "pattern": "^lprg_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lprg_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "ProgramStringFilterConditions": { "type": "object", "description": "Filter conditions for string fields (STRING field type). Allowed conditions:\n`$is`, `$is_not`, `$contains`, `$not_contain`, `$starts_with`, `$ends_with`,\n`$in`, `$not_in`, `$has_value`, `$is_unknown`. Each condition accepts a single\nstring or an array of strings (max 1 item, except `$in`/`$not_in` which allow\nup to 10 items).", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Field equals the given value.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Field does not equal the given value.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$contains": { "description": "Field contains the given substring.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$not_contain": { "description": "Field does not contain the given substring.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$starts_with": { "description": "Field starts with the given prefix.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$ends_with": { "description": "Field ends with the given suffix.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Field equals any of the given values (up to 10).", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] }, "$not_in": { "description": "Field equals none of the given values (up to 10).", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] }, "$has_value": { "description": "Field has a value (is not null).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] }, "$is_unknown": { "description": "Field has no value (is null).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "ProgramStatusFilterConditions": { "type": "object", "description": "Filter conditions for the program `status` field (ENUM field type). Allowed conditions:\n`$is`, `$is_not`, `$in`, `$not_in`. Allowed values: `ACTIVE`, `INACTIVE`, `DRAFT`.\nEach condition accepts a single value or an array of values (max 1 item for\n`$is`/`$is_not`, up to 10 items for `$in`/`$not_in`).", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Field equals the given status.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] }, { "type": "array", "items": { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Field does not equal the given status.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] }, { "type": "array", "items": { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Field equals any of the given statuses (up to 10).", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] }, { "type": "array", "items": { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] }, "$not_in": { "description": "Field equals none of the given statuses (up to 10).", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] }, { "type": "array", "items": { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "ProgramDateFilterConditions": { "type": "object", "description": "Filter conditions for date fields (DATE field type). Allowed conditions:\n`$before`, `$after` (date values), `$is`, `$more_than`, `$less_than`\n(non-negative integers, interpreted as a number of days), `$has_value`, `$is_unknown`.\nEach condition accepts a single value or an array with a single value.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$before": { "description": "Field is before the given date.", "oneOf": [ { "type": "string", "format": "date-time" }, { "type": "array", "items": { "type": "string", "format": "date-time" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$after": { "description": "Field is after the given date.", "oneOf": [ { "type": "string", "format": "date-time" }, { "type": "array", "items": { "type": "string", "format": "date-time" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is": { "description": "Field is exactly the given number of days ago. A non-negative integer number of days.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$more_than": { "description": "Field is more than the given number of days ago. A non-negative integer number of days.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$less_than": { "description": "Field is less than the given number of days ago. A non-negative integer number of days.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$has_value": { "description": "Field has a value (is not null).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] }, "$is_unknown": { "description": "Field has no value (is null).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "ProgramListFilters": { "type": "object", "description": "Filters accepted by the program list endpoint.", "properties": { "junction": { "description": "Logical junction applied between field filters. Defaults to `AND`.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by program id.", "oneOf": [ { "$ref": "#/components/schemas/ProgramIdFilterConditions" }, { "type": "null" } ] }, "name": { "description": "Filter by program name.", "oneOf": [ { "$ref": "#/components/schemas/ProgramStringFilterConditions" }, { "type": "null" } ] }, "status": { "description": "Filter by program status.", "oneOf": [ { "$ref": "#/components/schemas/ProgramStatusFilterConditions" }, { "type": "null" } ] }, "created_at": { "description": "Filter by program creation date.", "oneOf": [ { "$ref": "#/components/schemas/ProgramDateFilterConditions" }, { "type": "null" } ] } }, "additionalProperties": false }, "ProgramActivityIdFilterConditions": { "type": "object", "description": "Filter conditions for the activity `id` field (ID field type). Allowed conditions:\n`$is`, `$is_not`, `$in`, `$not_in`. Values must match the program activity id pattern\n`^laprg_[a-f0-9]+$`. Each condition accepts a single string or an array of strings\n(max 1 item for `$is`/`$is_not`, max 100 items for `$in`/`$not_in`).", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Field equals the given id.", "oneOf": [ { "type": "string", "pattern": "^laprg_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^laprg_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Field does not equal the given id.", "oneOf": [ { "type": "string", "pattern": "^laprg_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^laprg_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Field equals any of the given ids.", "oneOf": [ { "type": "string", "pattern": "^laprg_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^laprg_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Field equals none of the given ids.", "oneOf": [ { "type": "string", "pattern": "^laprg_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^laprg_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "ProgramActivityTypeFilterConditions": { "type": "object", "description": "Filter conditions for the activity `type` field (ENUM field type). Allowed conditions:\n`$is`, `$is_not`, `$in`, `$not_in`. Allowed values are the program activity types.\nEach condition accepts a single value or an array of values (max 1 item for\n`$is`/`$is_not`, up to 10 items for `$in`/`$not_in`).", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Field equals the given type.", "oneOf": [ { "type": "string", "enum": [ "vl.program.created", "vl.program.updated", "vl.program.deleted", "vl.program.activated", "vl.program.deactivated", "vl.program.card_definition.assigned", "vl.program.card_definition.unassigned", "vl.program.earning_rule.assigned", "vl.program.earning_rule.unassigned", "vl.program.reward.assigned", "vl.program.reward.unassigned", "vl.program.reward.updated", "vl.program.tier_structure.assigned", "vl.program.tier_structure.unassigned" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.program.created", "vl.program.updated", "vl.program.deleted", "vl.program.activated", "vl.program.deactivated", "vl.program.card_definition.assigned", "vl.program.card_definition.unassigned", "vl.program.earning_rule.assigned", "vl.program.earning_rule.unassigned", "vl.program.reward.assigned", "vl.program.reward.unassigned", "vl.program.reward.updated", "vl.program.tier_structure.assigned", "vl.program.tier_structure.unassigned" ] }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Field does not equal the given type.", "oneOf": [ { "type": "string", "enum": [ "vl.program.created", "vl.program.updated", "vl.program.deleted", "vl.program.activated", "vl.program.deactivated", "vl.program.card_definition.assigned", "vl.program.card_definition.unassigned", "vl.program.earning_rule.assigned", "vl.program.earning_rule.unassigned", "vl.program.reward.assigned", "vl.program.reward.unassigned", "vl.program.reward.updated", "vl.program.tier_structure.assigned", "vl.program.tier_structure.unassigned" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.program.created", "vl.program.updated", "vl.program.deleted", "vl.program.activated", "vl.program.deactivated", "vl.program.card_definition.assigned", "vl.program.card_definition.unassigned", "vl.program.earning_rule.assigned", "vl.program.earning_rule.unassigned", "vl.program.reward.assigned", "vl.program.reward.unassigned", "vl.program.reward.updated", "vl.program.tier_structure.assigned", "vl.program.tier_structure.unassigned" ] }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Field equals any of the given types (up to 10).", "oneOf": [ { "type": "string", "enum": [ "vl.program.created", "vl.program.updated", "vl.program.deleted", "vl.program.activated", "vl.program.deactivated", "vl.program.card_definition.assigned", "vl.program.card_definition.unassigned", "vl.program.earning_rule.assigned", "vl.program.earning_rule.unassigned", "vl.program.reward.assigned", "vl.program.reward.unassigned", "vl.program.reward.updated", "vl.program.tier_structure.assigned", "vl.program.tier_structure.unassigned" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.program.created", "vl.program.updated", "vl.program.deleted", "vl.program.activated", "vl.program.deactivated", "vl.program.card_definition.assigned", "vl.program.card_definition.unassigned", "vl.program.earning_rule.assigned", "vl.program.earning_rule.unassigned", "vl.program.reward.assigned", "vl.program.reward.unassigned", "vl.program.reward.updated", "vl.program.tier_structure.assigned", "vl.program.tier_structure.unassigned" ] }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] }, "$not_in": { "description": "Field equals none of the given types (up to 10).", "oneOf": [ { "type": "string", "enum": [ "vl.program.created", "vl.program.updated", "vl.program.deleted", "vl.program.activated", "vl.program.deactivated", "vl.program.card_definition.assigned", "vl.program.card_definition.unassigned", "vl.program.earning_rule.assigned", "vl.program.earning_rule.unassigned", "vl.program.reward.assigned", "vl.program.reward.unassigned", "vl.program.reward.updated", "vl.program.tier_structure.assigned", "vl.program.tier_structure.unassigned" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.program.created", "vl.program.updated", "vl.program.deleted", "vl.program.activated", "vl.program.deactivated", "vl.program.card_definition.assigned", "vl.program.card_definition.unassigned", "vl.program.earning_rule.assigned", "vl.program.earning_rule.unassigned", "vl.program.reward.assigned", "vl.program.reward.unassigned", "vl.program.reward.updated", "vl.program.tier_structure.assigned", "vl.program.tier_structure.unassigned" ] }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "ProgramActivityListFilters": { "type": "object", "description": "Filters accepted by the program activities list endpoint.", "properties": { "junction": { "description": "Logical junction applied between field filters. Defaults to `AND`.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by activity id.", "oneOf": [ { "$ref": "#/components/schemas/ProgramActivityIdFilterConditions" }, { "type": "null" } ] }, "type": { "description": "Filter by activity type.", "oneOf": [ { "$ref": "#/components/schemas/ProgramActivityTypeFilterConditions" }, { "type": "null" } ] }, "created_at": { "description": "Filter by activity creation date.", "oneOf": [ { "$ref": "#/components/schemas/ProgramDateFilterConditions" }, { "type": "null" } ] } }, "additionalProperties": false }, "MemberCreateRequest": { "type": "object", "description": "Request body for creating a program member. No additional properties are allowed.", "properties": { "customer_id": { "type": "string", "pattern": "^cust_[a-zA-Z0-9]+", "description": "ID of an existing customer to enroll as a member. Required." }, "status": { "description": "Initial member status. Defaults to `ACTIVE` when omitted or null.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE" ] }, { "type": "null" } ], "default": "ACTIVE" }, "metadata": { "description": "Free-form metadata attached to the member. Validated against the metadata\nschema defined for the `vl_member` related object (when one is configured).\nDefaults to an empty object.", "oneOf": [ { "type": "object" }, { "type": "null" } ], "default": {} } }, "required": [ "customer_id" ], "additionalProperties": false }, "MemberUpdateRequest": { "type": "object", "description": "Request body for updating a program member. Only metadata is updatable. No additional properties are allowed.", "properties": { "metadata": { "description": "Member metadata to apply. Object keys are merged into existing metadata (omitted keys are preserved). Validated against the `vl_member` metadata schema when configured. Pass `null` to clear all metadata.", "oneOf": [ { "type": "object" }, { "type": "null" } ] } }, "required": [ "metadata" ], "additionalProperties": false }, "MemberBatchCreateRequest": { "type": "array", "description": "Request body for batch member creation - a JSON array of member entries. The raw\nbody is limited to 10485760 bytes (10 MB) and is processed asynchronously in\nbatches of 100 entries. Each entry is validated like a single member creation\nrequest during background processing; per-entry failures (invalid customer_id\nformat, unknown customer, invalid status, member already exists) are reported in\nthe async action result.", "items": { "$ref": "#/components/schemas/MemberBatchCreateItem" } }, "MemberBatchCreateItem": { "type": "object", "description": "A single member entry of the batch creation payload.", "properties": { "customer_id": { "type": "string", "pattern": "^cust_[a-zA-Z0-9]+", "description": "ID of an existing customer to enroll as a member. Required per entry." }, "status": { "description": "Initial member status. Defaults to `ACTIVE` when omitted.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE" ] }, { "type": "null" } ], "default": "ACTIVE" }, "metadata": { "description": "Free-form metadata attached to the member. Defaults to an empty object.", "oneOf": [ { "type": "object" }, { "type": "null" } ], "default": {} } }, "required": [ "customer_id" ] }, "MemberBatchScheduleResponse": { "type": "object", "description": "Result of scheduling the members batch creation.", "properties": { "async_action_id": { "type": "string", "pattern": "^aa_[a-f0-9]+$", "description": "ID of the scheduled async action processing the batch." } }, "required": [ "async_action_id" ] }, "CardPointsRequest": { "type": "object", "description": "Request body for a manual card points adjustment. No additional properties are\nallowed.", "properties": { "points": { "type": "integer", "minimum": -9007199254740991, "maximum": 9007199254740991, "description": "Number of points to adjust. Positive values add points (`ADMIN_CREDIT`\ntransaction), negative values subtract points (`ADMIN_DEBIT` transaction),\nzero results in no transaction (`NO_CHANGE`). Required." }, "reason": { "type": "string", "maxLength": 255, "description": "Optional reason for the adjustment, stored in the transaction details." } }, "required": [ "points" ], "additionalProperties": false }, "Member": { "type": "object", "description": "A loyalty program member.", "properties": { "id": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$", "description": "Unique member ID assigned by Voucherify." }, "customer_id": { "type": "string", "pattern": "^cust_[a-zA-Z0-9]+", "description": "Unique Voucherify ID of the customer enrolled as this member." }, "program_id": { "type": "string", "pattern": "^lprg_[a-f0-9]+$", "description": "Unique Voucherify ID of the loyalty program the member belongs to." }, "status": { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DELETED" ], "description": "Current member status. `INACTIVE` member can't earn points or redeem rewards." }, "metadata": { "type": "object", "description": "Free-form metadata attached to the member (empty object when none)." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the member was created (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Timestamp when the member was last updated (ISO 8601), or null if never updated." }, "object": { "type": "string", "const": "member", "description": "Object type marker, always `member`." } }, "required": [ "id", "customer_id", "program_id", "status", "metadata", "created_at", "updated_at", "object" ] }, "MemberWithCards": { "description": "A loyalty program member together with its loyalty cards. Returned by member\ncreate and get endpoints.", "allOf": [ { "$ref": "#/components/schemas/Member" }, { "type": "object", "properties": { "cards": { "description": "Member's loyalty cards - one per card definition assigned to the program. Card codes are generated asynchronously, so `card.code` may be `null` right after member creation.", "type": "array", "items": { "$ref": "#/components/schemas/MemberCard" } } }, "required": [ "cards" ] } ] }, "MemberCard": { "type": "object", "description": "A member's loyalty card - the member's assignment to the card (`member_role`, `created_at`) combined with the card details in the `card` object.", "properties": { "member_role": { "type": "string", "enum": [ "OWNER", "MEMBER" ], "description": "Role of the member on this card." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the card was assigned to the member (ISO 8601)." }, "card": { "description": "The loyalty card details, or null when the card is not available.", "oneOf": [ { "$ref": "#/components/schemas/CardSimple" }, { "type": "null" } ] }, "object": { "type": "string", "const": "member_card", "description": "Object type marker, always `member_card`." } }, "required": [ "member_role", "created_at", "card", "object" ] }, "MemberTierProgress": { "type": "object", "description": "Member's tier progress on a card.", "properties": { "current": { "description": "The member's current tier, or null.", "oneOf": [ { "$ref": "#/components/schemas/MemberTierProgressCurrent" }, { "type": "null" } ] }, "tier_structure": { "description": "Reference to the tier structure the progress relates to, or null.", "oneOf": [ { "$ref": "#/components/schemas/MemberTierProgressTierStructure" }, { "type": "null" } ] }, "risks": { "type": "array", "description": "Upcoming risks of losing or downgrading the current tier.", "items": { "$ref": "#/components/schemas/MemberTierProgressRisk" } }, "opportunities": { "type": "array", "description": "Opportunities to reach higher tiers.", "items": { "$ref": "#/components/schemas/MemberTierProgressOpportunity" } }, "object": { "type": "string", "const": "member_tier_progress", "description": "Object type marker, always `member_tier_progress`." } }, "required": [ "current", "tier_structure", "risks", "opportunities", "object" ] }, "MemberTierProgressTierStructure": { "type": "object", "description": "Simple tier structure reference.", "properties": { "id": { "type": "string", "pattern": "^lts_[a-f0-9]+$", "description": "Tier structure ID." }, "object": { "type": "string", "const": "tier_structure", "description": "Object type marker, always `tier_structure`." } }, "required": [ "id", "object" ] }, "MemberTierProgressCurrent": { "type": "object", "description": "The member's current tier.", "properties": { "id": { "type": "string", "pattern": "^lt_[a-f0-9]+$", "description": "Tier ID." }, "name": { "type": "string", "description": "Tier name." }, "activated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Timestamp when the tier was activated for the member (ISO 8601), or null." }, "expires_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Timestamp when the member's tier expires (ISO 8601), or null." }, "points": { "description": "Member's points position within the tier's points range, or null.", "oneOf": [ { "$ref": "#/components/schemas/MemberTierProgressPoints" }, { "type": "null" } ] } }, "required": [ "id", "name", "activated_at", "expires_at", "points" ] }, "MemberTierProgressPoints": { "type": "object", "description": "Points position within a tier.", "properties": { "current": { "type": "number", "description": "Member's current points counted towards the tier." }, "min": { "type": "number", "description": "Minimum points of the tier's range." }, "max": { "type": "number", "description": "Maximum points of the tier's range." } }, "required": [ "current", "min", "max" ] }, "MemberTierProgressRisk": { "type": "object", "description": "A risk of losing or downgrading the current tier.", "properties": { "type": { "type": "string", "enum": [ "TIER_DOWNGRADE", "TIER_LEFT" ], "description": "Risk type - `TIER_DOWNGRADE` when the member would fall to a lower tier, `TIER_LEFT` when the member would leave the tier structure entirely." }, "date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date when the risk materializes (ISO 8601), or null." }, "tier_id": { "type": [ "string", "null" ], "description": "ID of the tier the member would be downgraded to (`lt_[a-f0-9]+`), or null for `TIER_LEFT`." } }, "required": [ "type", "date", "tier_id" ] }, "MemberTierProgressOpportunity": { "type": "object", "description": "An opportunity to reach a higher tier.", "properties": { "valid_until": { "type": [ "string", "null" ], "format": "date-time", "description": "Deadline for taking advantage of the opportunity (ISO 8601), or null." }, "tier_id": { "type": [ "string", "null" ], "description": "ID of the tier that can be reached (`lt_[a-f0-9]+`), or null." }, "points": { "type": "number", "description": "Points needed to reach the tier." } }, "required": [ "valid_until", "tier_id", "points" ] }, "CardSimple": { "type": "object", "description": "A loyalty card in its simple representation, as embedded in member responses.", "properties": { "id": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$", "description": "Unique Voucherify ID of the card." }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "Unique Voucherify ID of the card definition the card was created from." }, "card_type": { "type": "string", "enum": [ "INDIVIDUAL" ], "description": "Card type. Currently only `INDIVIDUAL` is supported." }, "code": { "type": [ "string", "null" ], "description": "Human-readable card code. Card code generation is asynchronous - this field is `null` right after member creation and is populated shortly after, once the background code generation completes." }, "lifetime_bucket": { "$ref": "#/components/schemas/CardLifetimeBucket", "description": "Lifetime point counters of the card." }, "balance": { "$ref": "#/components/schemas/CardBalance", "description": "Current available balance calculated from the lifetime bucket." }, "next_expiration": { "description": "The nearest upcoming point expiration, or `null` when none is scheduled.", "oneOf": [ { "$ref": "#/components/schemas/CardNextExpiration" }, { "type": "null" } ] }, "next_activation": { "description": "The nearest upcoming pending point activation, or `null` when none is scheduled.", "oneOf": [ { "$ref": "#/components/schemas/CardNextActivation" }, { "type": "null" } ] }, "object": { "type": "string", "const": "card", "description": "Object type marker, always `card`." } }, "required": [ "id", "card_definition_id", "card_type", "code", "lifetime_bucket", "balance", "next_expiration", "next_activation", "object" ] }, "CardLifetimeBucket": { "type": "object", "description": "Lifetime points counters of a card.", "properties": { "points": { "$ref": "#/components/schemas/CardLifetimeBucketPoints", "description": "Lifetime counters of regular (active) points." }, "pending_points": { "$ref": "#/components/schemas/CardLifetimeBucketPendingPoints", "description": "Lifetime counters of pending points." } }, "required": [ "points", "pending_points" ] }, "CardLifetimeBucketPoints": { "type": "object", "description": "Lifetime counters of regular points. All counters default to 0. The available balance is calculated as: `total` - `subtracted` - `expired` - `spent` - `refunded` + `returned` - `locked` + `unlocked` - `purchased_reversed`.", "properties": { "total": { "type": "number", "description": "Total accumulated points, including points added manually, earned by fulfilling earning rules and activated from pending points (excluding returned points).", "default": 0 }, "earned": { "type": "number", "description": "Total points earned by fulfilling earning rules (does not include activated pending points or points added manually).", "default": 0 }, "added": { "type": "number", "description": "Total manually added points.", "default": 0 }, "purchased": { "type": "number", "description": "Total points purchased via a `LOYALTY_CARD_POINTS` reward (credited to the target card).", "default": 0 }, "purchased_reversed": { "type": "number", "description": "Total purchased points reversed via reward refund.", "default": 0 }, "subtracted": { "type": "number", "description": "Total manually subtracted points.", "default": 0 }, "expired": { "type": "number", "description": "Total expired points.", "default": 0 }, "spent": { "type": "number", "description": "Total points spent on rewards.", "default": 0 }, "refunded": { "type": "number", "description": "Total refunded points (points that were earned by products which were later returned).", "default": 0 }, "returned": { "type": "number", "description": "Total returned points (by returning a purchased reward).", "default": 0 }, "locked": { "type": "number", "description": "Total locked points (by locking a purchased reward).", "default": 0 }, "unlocked": { "type": "number", "description": "Total unlocked points (by unlocking a purchased reward).", "default": 0 } }, "required": [ "total", "earned", "added", "purchased", "purchased_reversed", "subtracted", "expired", "spent", "refunded", "returned", "locked", "unlocked" ] }, "CardLifetimeBucketPendingPoints": { "type": "object", "description": "Lifetime counters of pending points. The available pending balance is max(`total` - `activated` - `canceled`, 0).", "properties": { "total": { "type": "number", "description": "Total pending points ever added.", "default": 0 }, "activated": { "type": "number", "description": "Total pending points activated into regular points.", "default": 0 }, "canceled": { "type": "number", "description": "Total pending points canceled.", "default": 0 } }, "required": [ "total", "activated", "canceled" ] }, "CardBalance": { "type": "object", "description": "Current available balance of a card.", "properties": { "points": { "type": "number", "description": "Currently available regular points.", "default": 0 }, "pending_points": { "type": "number", "description": "Currently pending (not yet activated) points.", "default": 0 } }, "required": [ "points", "pending_points" ] }, "CardNextExpiration": { "type": "object", "description": "The nearest upcoming points expiration on a card.", "properties": { "points": { "type": "number", "description": "Number of points that will expire.", "default": 0 }, "date": { "type": "string", "format": "date", "description": "Date when the points expire (`YYYY-MM-DD`)." } }, "required": [ "points", "date" ] }, "CardNextActivation": { "type": "object", "description": "The nearest upcoming pending points activation on a card. For the `EVENT_BASED` type, `date` is omitted and `cancel_date` is returned instead; for other types `date` is returned and `cancel_date` is omitted.", "properties": { "points": { "type": "number", "description": "Number of pending points to be activated.", "default": 0 }, "type": { "type": "string", "enum": [ "IMMEDIATE", "PERIOD_BASED", "FIXED_DATES", "EVENT_BASED" ], "description": "Pending points activation type from the card definition." }, "date": { "type": "string", "format": "date", "description": "Activation date (`YYYY-MM-DD`). Present for all types except `EVENT_BASED`." }, "cancel_date": { "type": "string", "format": "date", "description": "Date when the pending points are canceled if the activating event does not occur (`YYYY-MM-DD`). Present only for the `EVENT_BASED` type." } }, "required": [ "points", "type" ] }, "MemberListResponse": { "type": "object", "description": "Cursor-paginated list of members.", "properties": { "data": { "type": "array", "description": "Members on the current page (without the `cards` array).", "items": { "$ref": "#/components/schemas/Member" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/MemberListCursor" }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type marker, always `list`." } }, "required": [ "data", "cursor", "object" ] }, "MemberListCursor": { "type": "object", "description": "Pagination cursor.", "properties": { "next": { "type": "string", "description": "Cursor value to pass as the `cursor` query parameter to fetch the next page." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp when the cursor expires." } }, "required": [ "next" ] }, "MemberListFilters": { "type": "object", "description": "Filters for the members list. Each field accepts a `conditions` object; multiple\nfield filters are combined with the `junction` (default AND).", "properties": { "junction": { "description": "How multiple field filters are combined. Defaults to `AND`.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by member ID (ID conditions, values matching `^lmbr_[a-f0-9]+$`).", "oneOf": [ { "$ref": "#/components/schemas/MemberIdFilter" }, { "type": "null" } ] }, "status": { "description": "Filter by member status (enum conditions, values `ACTIVE` or `INACTIVE`).", "oneOf": [ { "$ref": "#/components/schemas/MemberStatusFilter" }, { "type": "null" } ] }, "customer_id": { "description": "Filter by customer ID (ID conditions, values matching `^cust_[a-zA-Z0-9]+`).", "oneOf": [ { "$ref": "#/components/schemas/MemberCustomerIdFilter" }, { "type": "null" } ] }, "created_at": { "description": "Filter by creation date (date conditions).", "oneOf": [ { "$ref": "#/components/schemas/MemberDateFilter" }, { "type": "null" } ] } }, "additionalProperties": false }, "MemberIdFilter": { "type": "object", "description": "ID filter conditions for member IDs. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "description": "Value equals. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Value does not equal. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Value is one of. Single value or an array of 1-100 values.", "oneOf": [ { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Value is not one of. Single value or an array of 1-100 values.", "oneOf": [ { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "MemberCustomerIdFilter": { "type": "object", "description": "ID filter conditions for customer IDs. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "description": "Value equals. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "pattern": "^cust_[a-zA-Z0-9]+" }, { "type": "array", "items": { "type": "string", "pattern": "^cust_[a-zA-Z0-9]+" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Value does not equal. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "pattern": "^cust_[a-zA-Z0-9]+" }, { "type": "array", "items": { "type": "string", "pattern": "^cust_[a-zA-Z0-9]+" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Value is one of. Single value or an array of 1-100 values.", "oneOf": [ { "type": "string", "pattern": "^cust_[a-zA-Z0-9]+" }, { "type": "array", "items": { "type": "string", "pattern": "^cust_[a-zA-Z0-9]+" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Value is not one of. Single value or an array of 1-100 values.", "oneOf": [ { "type": "string", "pattern": "^cust_[a-zA-Z0-9]+" }, { "type": "array", "items": { "type": "string", "pattern": "^cust_[a-zA-Z0-9]+" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "MemberStatusFilter": { "type": "object", "description": "Enum filter conditions for member status. Allowed values are `ACTIVE` and\n`INACTIVE`. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "description": "Value equals. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE" ] }, { "type": "array", "items": { "type": "string", "enum": [ "ACTIVE", "INACTIVE" ] }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Value does not equal. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE" ] }, { "type": "array", "items": { "type": "string", "enum": [ "ACTIVE", "INACTIVE" ] }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Value is one of. Single value or an array of 1-10 values.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE" ] }, { "type": "array", "items": { "type": "string", "enum": [ "ACTIVE", "INACTIVE" ] }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] }, "$not_in": { "description": "Value is not one of. Single value or an array of 1-10 values.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE" ] }, { "type": "array", "items": { "type": "string", "enum": [ "ACTIVE", "INACTIVE" ] }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "MemberDateFilter": { "type": "object", "description": "Date filter conditions. `$before`/`$after` take date strings; `$is`,\n`$more_than`, `$less_than` take non-negative integers;\n`$has_value`/`$is_unknown` are presence checks. Each condition accepts a single\nvalue or an array with exactly one value. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$before": { "description": "Date is before the given date.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$after": { "description": "Date is after the given date.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is": { "description": "Date matches the given non-negative integer value.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$more_than": { "description": "More than the given non-negative integer value.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$less_than": { "description": "Less than the given non-negative integer value.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$has_value": { "description": "Field has a value (presence check).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] }, "$is_unknown": { "description": "Field has no value (absence check).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "MemberActivityListResponse": { "type": "object", "description": "Cursor-paginated list of member activities.", "properties": { "data": { "type": "array", "description": "Member activities on the current page.", "items": { "$ref": "#/components/schemas/MemberActivity" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/MemberListCursor" }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type marker, always `list`." } }, "required": [ "data", "cursor", "object" ] }, "MemberActivity": { "type": "object", "description": "An activity recorded for a member.", "properties": { "id": { "type": "string", "pattern": "^lambr_[a-f0-9]+$", "description": "Unique activity ID." }, "member_id": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$", "description": "ID of the member the activity relates to." }, "type": { "type": "string", "enum": [ "vl.member.created", "vl.member.updated", "vl.member.deleted", "vl.member.activated", "vl.member.deactivated", "vl.member.card.assigned", "vl.member.card.unassigned" ], "description": "Activity type." }, "data": { "type": "object", "description": "Activity payload - snapshots of the objects involved at the time of the activity (e.g. `member` and `program` objects for member lifecycle activities)." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the activity was recorded (ISO 8601)." }, "group_id": { "type": "string", "description": "ID grouping activities recorded within the same request." }, "source": { "$ref": "#/components/schemas/MemberActivitySource", "description": "Origin of the activity. Omitted when not available." } }, "required": [ "id", "member_id", "type", "data", "created_at" ] }, "MemberActivitySource": { "type": "object", "description": "Origin of an activity.", "properties": { "channel": { "type": "string", "enum": [ "USER_PORTAL", "API", "CLIENT_API", "INTERNAL" ], "description": "Channel through which the activity was triggered." }, "user": { "type": "object", "description": "The dashboard user who triggered the activity. Omitted when not applicable.", "properties": { "id": { "type": "string", "description": "User ID." } } }, "api_key": { "type": "object", "description": "The API key used to trigger the activity. Omitted when not applicable.", "properties": { "name": { "type": "string", "description": "API key name." }, "app_id": { "type": "string", "description": "Application ID of the API key." }, "client_app_id": { "type": "string", "description": "Client application ID of the API key." } } } } }, "MemberActivityListFilters": { "type": "object", "description": "Filters for the member activities list.", "properties": { "junction": { "description": "How multiple field filters are combined. Defaults to `AND`.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by activity ID (ID conditions, values matching `^lambr_[a-f0-9]+$`).", "oneOf": [ { "$ref": "#/components/schemas/MemberActivityIdFilter" }, { "type": "null" } ] }, "type": { "description": "Filter by activity type (enum conditions over the member activity types).", "oneOf": [ { "$ref": "#/components/schemas/MemberActivityTypeFilter" }, { "type": "null" } ] }, "created_at": { "description": "Filter by activity creation date (date conditions).", "oneOf": [ { "$ref": "#/components/schemas/MemberDateFilter" }, { "type": "null" } ] } }, "additionalProperties": false }, "MemberActivityIdFilter": { "type": "object", "description": "ID filter conditions for member activity IDs. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "description": "Value equals. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "pattern": "^lambr_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lambr_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Value does not equal. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "pattern": "^lambr_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lambr_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Value is one of. Single value or an array of 1-100 values.", "oneOf": [ { "type": "string", "pattern": "^lambr_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lambr_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Value is not one of. Single value or an array of 1-100 values.", "oneOf": [ { "type": "string", "pattern": "^lambr_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lambr_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "MemberActivityTypeFilter": { "type": "object", "description": "Enum filter conditions for member activity types. At least one condition is\nrequired.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "description": "Value equals. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "enum": [ "vl.member.created", "vl.member.updated", "vl.member.deleted", "vl.member.activated", "vl.member.deactivated", "vl.member.card.assigned", "vl.member.card.unassigned" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.member.created", "vl.member.updated", "vl.member.deleted", "vl.member.activated", "vl.member.deactivated", "vl.member.card.assigned", "vl.member.card.unassigned" ] }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Value does not equal. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "enum": [ "vl.member.created", "vl.member.updated", "vl.member.deleted", "vl.member.activated", "vl.member.deactivated", "vl.member.card.assigned", "vl.member.card.unassigned" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.member.created", "vl.member.updated", "vl.member.deleted", "vl.member.activated", "vl.member.deactivated", "vl.member.card.assigned", "vl.member.card.unassigned" ] }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Value is one of. Single value or an array of 1-10 values.", "oneOf": [ { "type": "string", "enum": [ "vl.member.created", "vl.member.updated", "vl.member.deleted", "vl.member.activated", "vl.member.deactivated", "vl.member.card.assigned", "vl.member.card.unassigned" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.member.created", "vl.member.updated", "vl.member.deleted", "vl.member.activated", "vl.member.deactivated", "vl.member.card.assigned", "vl.member.card.unassigned" ] }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] }, "$not_in": { "description": "Value is not one of. Single value or an array of 1-10 values.", "oneOf": [ { "type": "string", "enum": [ "vl.member.created", "vl.member.updated", "vl.member.deleted", "vl.member.activated", "vl.member.deactivated", "vl.member.card.assigned", "vl.member.card.unassigned" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.member.created", "vl.member.updated", "vl.member.deleted", "vl.member.activated", "vl.member.deactivated", "vl.member.card.assigned", "vl.member.card.unassigned" ] }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "CardActivityListResponse": { "type": "object", "description": "Cursor-paginated list of card activities.", "properties": { "data": { "type": "array", "description": "Card activities on the current page.", "items": { "$ref": "#/components/schemas/CardActivity" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/MemberListCursor" }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type marker, always `list`." } }, "required": [ "data", "cursor", "object" ] }, "CardActivity": { "type": "object", "description": "An activity recorded for a card.", "properties": { "id": { "type": "string", "pattern": "^lacrd_[a-f0-9]+$", "description": "Unique activity ID." }, "card_id": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$", "description": "ID of the card the activity relates to." }, "type": { "type": "string", "enum": [ "vl.card.created", "vl.card.assigned", "vl.card.unassigned", "vl.card.code_generation.succeeded", "vl.card.code_generation.failed" ], "description": "Activity type." }, "data": { "type": "object", "description": "Activity payload - snapshots of the objects involved at the time of the activity." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the activity was recorded (ISO 8601)." }, "group_id": { "type": "string", "description": "ID grouping activities recorded within the same request." }, "source": { "$ref": "#/components/schemas/MemberActivitySource", "description": "Origin of the activity. Omitted when not available." } }, "required": [ "id", "card_id", "type", "data", "created_at" ] }, "CardActivityListFilters": { "type": "object", "description": "Filters for the card activities list.", "properties": { "junction": { "description": "How multiple field filters are combined. Defaults to `AND`.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by activity ID (ID conditions, values matching `^lacrd_[a-f0-9]+$`).", "oneOf": [ { "$ref": "#/components/schemas/CardActivityIdFilter" }, { "type": "null" } ] }, "type": { "description": "Filter by activity type (enum conditions over the card activity types).", "oneOf": [ { "$ref": "#/components/schemas/CardActivityTypeFilter" }, { "type": "null" } ] }, "created_at": { "description": "Filter by activity creation date (date conditions).", "oneOf": [ { "$ref": "#/components/schemas/MemberDateFilter" }, { "type": "null" } ] } }, "additionalProperties": false }, "CardActivityIdFilter": { "type": "object", "description": "ID filter conditions for card activity IDs. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "description": "Value equals. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "pattern": "^lacrd_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lacrd_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Value does not equal. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "pattern": "^lacrd_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lacrd_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Value is one of. Single value or an array of 1-100 values.", "oneOf": [ { "type": "string", "pattern": "^lacrd_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lacrd_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Value is not one of. Single value or an array of 1-100 values.", "oneOf": [ { "type": "string", "pattern": "^lacrd_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lacrd_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "CardActivityTypeFilter": { "type": "object", "description": "Enum filter conditions for card activity types. At least one condition is\nrequired.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "description": "Value equals. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "enum": [ "vl.card.created", "vl.card.assigned", "vl.card.unassigned", "vl.card.code_generation.succeeded", "vl.card.code_generation.failed" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.card.created", "vl.card.assigned", "vl.card.unassigned", "vl.card.code_generation.succeeded", "vl.card.code_generation.failed" ] }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Value does not equal. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "enum": [ "vl.card.created", "vl.card.assigned", "vl.card.unassigned", "vl.card.code_generation.succeeded", "vl.card.code_generation.failed" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.card.created", "vl.card.assigned", "vl.card.unassigned", "vl.card.code_generation.succeeded", "vl.card.code_generation.failed" ] }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Value is one of. Single value or an array of 1-10 values.", "oneOf": [ { "type": "string", "enum": [ "vl.card.created", "vl.card.assigned", "vl.card.unassigned", "vl.card.code_generation.succeeded", "vl.card.code_generation.failed" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.card.created", "vl.card.assigned", "vl.card.unassigned", "vl.card.code_generation.succeeded", "vl.card.code_generation.failed" ] }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] }, "$not_in": { "description": "Value is not one of. Single value or an array of 1-10 values.", "oneOf": [ { "type": "string", "enum": [ "vl.card.created", "vl.card.assigned", "vl.card.unassigned", "vl.card.code_generation.succeeded", "vl.card.code_generation.failed" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.card.created", "vl.card.assigned", "vl.card.unassigned", "vl.card.code_generation.succeeded", "vl.card.code_generation.failed" ] }, "minItems": 1, "maxItems": 10 }, { "type": "null" } ] } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "CardPointsAdjustmentResult": { "type": "object", "description": "Result of a manual card points adjustment.", "properties": { "transaction": { "description": "The created card transaction (`ADMIN_CREDIT` or `ADMIN_DEBIT`), or null when no transaction was created (status `NO_CHANGE`).", "oneOf": [ { "$ref": "#/components/schemas/CardTransaction" }, { "type": "null" } ] }, "status": { "type": "string", "enum": [ "TRANSACTION_CREATED", "NO_CHANGE" ], "description": "`TRANSACTION_CREATED` when a transaction was created, `NO_CHANGE` when the requested points amount was zero." }, "message": { "type": "string", "description": "Human-readable result message - \"Points addition transaction created\", \"Points subtraction transaction created\" or \"Provided amount is zero, transaction was not created\"." } }, "required": [ "transaction", "status", "message" ] }, "CardPendingPointsActivationResult": { "type": "object", "description": "Result of a manual pending points activation. This endpoint always returns\nstatus `TRANSACTION_CREATED` on success.", "properties": { "transaction": { "description": "The created `PENDING_POINTS_ACTIVATED` card transaction, or null.", "oneOf": [ { "$ref": "#/components/schemas/CardTransaction" }, { "type": "null" } ] }, "status": { "type": "string", "enum": [ "TRANSACTION_CREATED", "NO_ACTIVATION" ], "description": "Result status. The API endpoint returns `TRANSACTION_CREATED`." }, "message": { "type": "string", "description": "Human-readable result message - \"Points activation transaction created\"." } }, "required": [ "transaction", "status", "message" ] }, "CardPendingPointsCancellationResult": { "type": "object", "description": "Result of a pending points cancellation. This endpoint always returns status\n`TRANSACTION_CREATED` on success.", "properties": { "transaction": { "description": "The created `PENDING_POINTS_CANCELED` card transaction, or null.", "oneOf": [ { "$ref": "#/components/schemas/CardTransaction" }, { "type": "null" } ] }, "status": { "type": "string", "enum": [ "TRANSACTION_CREATED", "NO_CANCELLATION" ], "description": "Result status. The API endpoint returns `TRANSACTION_CREATED`." }, "message": { "type": "string", "description": "Human-readable result message - \"Points cancellation transaction created\"." } }, "required": [ "transaction", "status", "message" ] }, "CardPointsExpirationResult": { "type": "object", "description": "Result of a manual points bucket expiration. This endpoint always returns status\n`TRANSACTION_CREATED` on success.", "properties": { "transaction": { "description": "The created `ADMIN_POINTS_EXPIRATION` card transaction, or null.", "oneOf": [ { "$ref": "#/components/schemas/CardTransaction" }, { "type": "null" } ] }, "status": { "type": "string", "enum": [ "TRANSACTION_CREATED", "NO_EXPIRATION" ], "description": "Result status. The API endpoint returns `TRANSACTION_CREATED`." }, "message": { "type": "string", "description": "Human-readable result message - \"Points expiration transaction created\"." } }, "required": [ "transaction", "status", "message" ] }, "CardTransactionListResponse": { "type": "object", "description": "Cursor-paginated list of card transactions.", "properties": { "data": { "type": "array", "description": "Card transactions on the current page.", "items": { "$ref": "#/components/schemas/CardTransaction" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/MemberListCursor" }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type marker, always `list`." } }, "required": [ "data", "cursor", "object" ] }, "CardTransaction": { "type": "object", "description": "A card transaction.", "properties": { "id": { "type": "string", "pattern": "^lctx_[a-f0-9]+$", "description": "Unique card transaction ID." }, "card_id": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$", "description": "ID of the card the transaction belongs to." }, "program_id": { "type": "string", "pattern": "^lprg_[a-f0-9]+$", "description": "ID of the loyalty program." }, "member_id": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$", "description": "ID of the member owning the card." }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "ID of the card definition of the card." }, "card_type": { "type": "string", "enum": [ "INDIVIDUAL" ], "description": "Card type." }, "type": { "type": "string", "enum": [ "ADMIN_CREDIT", "ADMIN_DEBIT", "ADMIN_POINTS_EXPIRATION", "POINTS_EARNED", "POINTS_SPENT_ON_REWARD", "POINTS_PURCHASED", "POINTS_PURCHASE_REVERSED", "POINTS_SPENT_ON_ORDER", "POINTS_REFUNDED", "POINTS_RETURNED", "POINTS_EXPIRED", "PENDING_POINTS_ADDED", "PENDING_POINTS_ACTIVATED", "PENDING_POINTS_CANCELED" ], "description": "Transaction type." }, "details": { "description": "Transaction details; the shape depends on the transaction `type`.", "oneOf": [ { "$ref": "#/components/schemas/CardTransactionDetails" }, { "type": "null" } ] }, "status": { "type": "string", "enum": [ "PENDING", "PROCESSING", "APPROVED", "REJECTED" ], "description": "Transaction processing status. Transactions are created as `PENDING` and processed asynchronously." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the transaction was created (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Timestamp when the transaction was last updated (ISO 8601), or null." }, "object": { "type": "string", "const": "card_transaction", "description": "Object type marker, always `card_transaction`." } }, "required": [ "id", "card_id", "program_id", "member_id", "card_definition_id", "card_type", "type", "details", "status", "created_at", "updated_at", "object" ] }, "CardTransactionDetails": { "type": "object", "description": "Card transaction details. `reason`, `rejection` and `metadata` are present on all\nvariants; the remaining fields depend on the transaction `type`:\n\n- `ADMIN_CREDIT`: `points` (`total`, `expiration_date`)\n- `ADMIN_DEBIT`: `points` (`total`)\n- `ADMIN_POINTS_EXPIRATION`: `bucket` (the expired points bucket)\n- `POINTS_EARNED`: `points` (`total`, `expiration_date`)\n- `POINTS_EXPIRED`: `points` (`total`), `date`, `buckets`\n- `POINTS_SPENT_ON_REWARD`: `points` (`total`), `reward`, `reward_transaction`,\n `target_card`, `purchase_transaction`\n- `POINTS_PURCHASED`: `points` (`total`, `expiration_date`, `expiration_type`),\n `reward`, `reward_transaction`, `card_transaction`\n- `POINTS_PURCHASE_REVERSED`: `points` (`total`, `expiration_date`,\n `expiration_type`), `reward`, `purchase`, `reward_transaction`\n- `POINTS_SPENT_ON_ORDER`: `points` (`total`), `order`, `order_transaction`\n- `POINTS_REFUNDED`: `points` (`total`)\n- `POINTS_RETURNED`: `points` (`total`, `expiration_date`, `expiration_type`),\n `reward`, `purchase`, `reward_transaction`\n- `PENDING_POINTS_ADDED` / `PENDING_POINTS_ACTIVATED` / `PENDING_POINTS_CANCELED`:\n `points` (`total`, `date`, `type`)", "properties": { "reason": { "type": [ "string", "null" ], "description": "Reason for the transaction (e.g. the reason provided in a manual adjustment request)." }, "rejection": { "description": "Rejection details when the transaction was rejected, or null.", "oneOf": [ { "type": "object", "properties": { "reason": { "type": "string", "description": "Rejection reason." }, "details": { "type": "string", "description": "Detailed rejection description." } } }, { "type": "null" } ] }, "metadata": { "type": "object", "description": "Transaction metadata (empty object when none)." }, "points": { "type": "object", "description": "Points affected by the transaction (variant-dependent fields).", "properties": { "total": { "type": "number", "description": "Number of points. Negative for debits." }, "expiration_date": { "type": [ "string", "null" ], "format": "date", "description": "Expiration date of the affected points (`YYYY-MM-DD`), or null." }, "expiration_type": { "type": [ "string", "null" ], "enum": [ "NO_EXPIRATION", "ROLLING_EXPIRATION", "CALENDAR_EXPIRATION", "SLIDING_EXPIRATION", null ], "description": "Points expiration type of the affected points, or null." }, "date": { "type": "string", "format": "date", "description": "Activation date of the pending points (`YYYY-MM-DD`). Pending points variants only." }, "type": { "type": "string", "enum": [ "IMMEDIATE", "PERIOD_BASED", "FIXED_DATES", "EVENT_BASED" ], "description": "Pending points activation type. Pending points variants only." } } }, "bucket": { "$ref": "#/components/schemas/CardPointsBucketSimple", "description": "The points bucket being expired (`ADMIN_POINTS_EXPIRATION` only)." }, "buckets": { "type": "array", "description": "The points buckets that expired (`POINTS_EXPIRED` only).", "items": { "$ref": "#/components/schemas/CardPointsBucketSimple" } }, "date": { "type": "string", "format": "date", "description": "Expiration date (`POINTS_EXPIRED` only, `YYYY-MM-DD`)." }, "reward": { "description": "Reference to the reward involved, or null.", "oneOf": [ { "type": "object", "properties": { "id": { "type": "string", "description": "Reward ID (`lrew_[a-f0-9]+`)." } } }, { "type": "null" } ] }, "reward_transaction": { "description": "Reference to the related reward transaction, or null.", "oneOf": [ { "type": "object", "properties": { "id": { "type": "string", "description": "Reward transaction ID (`lrtx_[a-f0-9]+`)." } } }, { "type": "null" } ] }, "card_transaction": { "description": "Reference to the linked card transaction (e.g. the spend side of a points purchase), or null.", "oneOf": [ { "type": "object", "properties": { "id": { "type": "string", "description": "Card transaction ID (`lctx_[a-f0-9]+`)." } } }, { "type": "null" } ] }, "purchase": { "description": "References to the original purchase transactions (reversal/return variants), or null.", "oneOf": [ { "type": "object", "properties": { "card_transaction": { "oneOf": [ { "type": "object", "properties": { "id": { "type": "string", "description": "Card transaction ID (`lctx_[a-f0-9]+`)." } } }, { "type": "null" } ] }, "reward_transaction": { "oneOf": [ { "type": "object", "properties": { "id": { "type": "string", "description": "Reward transaction ID (`lrtx_[a-f0-9]+`)." } } }, { "type": "null" } ] } } }, { "type": "null" } ] }, "order": { "description": "Reference to the order paid with points (`POINTS_SPENT_ON_ORDER` only), or null.", "oneOf": [ { "type": "object", "properties": { "id": { "type": "string", "description": "Order ID." } } }, { "type": "null" } ] }, "order_transaction": { "description": "Reference to the related order transaction (`POINTS_SPENT_ON_ORDER` only), or null.", "oneOf": [ { "type": "object", "properties": { "id": { "type": "string", "description": "Order transaction ID (`lotx_[a-f0-9]+`)." } } }, { "type": "null" } ] }, "target_card": { "description": "Reference to the target card credited by a points purchase (`POINTS_SPENT_ON_REWARD` only), or null.", "oneOf": [ { "type": "object", "properties": { "id": { "type": "string", "description": "Card ID (`lcrd_[a-f0-9]+`)." } } }, { "type": "null" } ] }, "purchase_transaction": { "description": "Reference to the linked purchase card transaction (`POINTS_SPENT_ON_REWARD` only), or null.", "oneOf": [ { "type": "object", "properties": { "id": { "type": "string", "description": "Card transaction ID (`lctx_[a-f0-9]+`)." } } }, { "type": "null" } ] } } }, "CardTransactionListFilters": { "type": "object", "description": "Filters for the card transactions list.", "properties": { "junction": { "description": "How multiple field filters are combined. Defaults to `AND`.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by transaction ID (ID conditions, values matching `^lctx_[a-f0-9]+$`).", "oneOf": [ { "$ref": "#/components/schemas/CardTransactionIdFilter" }, { "type": "null" } ] }, "created_at": { "description": "Filter by transaction creation date (date conditions).", "oneOf": [ { "$ref": "#/components/schemas/MemberDateFilter" }, { "type": "null" } ] } }, "additionalProperties": false }, "CardTransactionIdFilter": { "type": "object", "description": "ID filter conditions for card transaction IDs. At least one condition is\nrequired.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "description": "Value equals. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "pattern": "^lctx_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lctx_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Value does not equal. Single value or an array with exactly one value.", "oneOf": [ { "type": "string", "pattern": "^lctx_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lctx_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Value is one of. Single value or an array of 1-100 values.", "oneOf": [ { "type": "string", "pattern": "^lctx_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lctx_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Value is not one of. Single value or an array of 1-100 values.", "oneOf": [ { "type": "string", "pattern": "^lctx_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lctx_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "CardPendingPointsBucketListResponse": { "type": "object", "description": "Cursor-paginated list of pending points buckets.", "properties": { "data": { "type": "array", "description": "Pending points buckets on the current page.", "items": { "$ref": "#/components/schemas/CardPendingPointsBucket" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/MemberListCursor" }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type marker, always `list`." } }, "required": [ "data", "cursor", "object" ] }, "CardPendingPointsBucket": { "type": "object", "description": "A pending points bucket of a card.", "properties": { "id": { "type": "string", "pattern": "^lcppb_[a-f0-9]+$", "description": "Unique pending points bucket ID." }, "card_id": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$", "description": "ID of the card the bucket belongs to." }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "ID of the card definition of the card." }, "program_id": { "type": "string", "pattern": "^lprg_[a-f0-9]+$", "description": "ID of the loyalty program." }, "card_type": { "type": "string", "enum": [ "INDIVIDUAL" ], "description": "Card type." }, "member_id": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$", "description": "ID of the member owning the card." }, "points": { "type": "object", "description": "Points held in the bucket.", "properties": { "total": { "type": "number", "description": "Number of pending points in the bucket." } }, "required": [ "total" ] }, "date": { "type": "string", "format": "date", "description": "Scheduled activation date of the pending points (`YYYY-MM-DD`). For the `EVENT_BASED` type this is the cancellation deadline." }, "type": { "type": "string", "enum": [ "IMMEDIATE", "PERIOD_BASED", "FIXED_DATES", "EVENT_BASED" ], "description": "Pending points activation type from the card definition." }, "status": { "type": "string", "enum": [ "PENDING", "ACTIVATED", "CANCELED", "DELETED" ], "description": "Bucket status." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the bucket was created (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Timestamp when the bucket was last updated (ISO 8601), or null." }, "object": { "type": "string", "const": "card_pending_points_bucket", "description": "Object type marker, always `card_pending_points_bucket`." } }, "required": [ "id", "card_id", "card_definition_id", "program_id", "card_type", "member_id", "points", "date", "type", "status", "created_at", "updated_at", "object" ] }, "CardPointsBucketListResponse": { "type": "object", "description": "Cursor-paginated list of points expiration buckets.", "properties": { "data": { "type": "array", "description": "Points expiration buckets on the current page.", "items": { "$ref": "#/components/schemas/CardPointsBucket" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/MemberListCursor" }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type marker, always `list`." } }, "required": [ "data", "cursor", "object" ] }, "CardPointsBucket": { "type": "object", "description": "A points expiration bucket of a card.", "properties": { "id": { "type": "string", "pattern": "^lcpeb_[a-f0-9]+$", "description": "Unique points expiration bucket ID." }, "card_id": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$", "description": "ID of the card the bucket belongs to." }, "customer_id": { "type": "string", "pattern": "^cust_[a-zA-Z0-9]+", "description": "ID of the customer owning the card." }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "ID of the card definition of the card." }, "program_id": { "type": "string", "pattern": "^lprg_[a-f0-9]+$", "description": "ID of the loyalty program." }, "card_type": { "type": "string", "enum": [ "INDIVIDUAL" ], "description": "Card type." }, "member_id": { "type": "string", "pattern": "^lmbr_[a-f0-9]+$", "description": "ID of the member owning the card." }, "points": { "type": "object", "description": "Points held in the bucket.", "properties": { "total": { "type": "number", "description": "Number of points in the bucket." } }, "required": [ "total" ] }, "expiration_date": { "type": "string", "format": "date", "description": "Date when the points in the bucket expire (`YYYY-MM-DD`)." }, "expiration_type": { "type": "string", "enum": [ "NO_EXPIRATION", "ROLLING_EXPIRATION", "CALENDAR_EXPIRATION", "SLIDING_EXPIRATION" ], "description": "Points expiration type from the card definition." }, "status": { "type": "string", "enum": [ "ACTIVE", "DELETED", "EXPIRED" ], "description": "Bucket status." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the bucket was created (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Timestamp when the bucket was last updated (ISO 8601), or null." }, "object": { "type": "string", "const": "card_points_bucket", "description": "Object type marker, always `card_points_bucket`." } }, "required": [ "id", "card_id", "customer_id", "card_definition_id", "program_id", "card_type", "member_id", "points", "expiration_date", "expiration_type", "status", "created_at", "updated_at", "object" ] }, "CardPointsBucketSimple": { "type": "object", "description": "Simple representation of a points expiration bucket, embedded in card\ntransaction details.", "properties": { "id": { "type": "string", "pattern": "^lcpeb_[a-f0-9]+$", "description": "Points expiration bucket ID." }, "points": { "type": "object", "description": "Points held in the bucket.", "properties": { "total": { "type": "number", "description": "Number of points in the bucket." } }, "required": [ "total" ] }, "expiration_date": { "type": "string", "format": "date", "description": "Date when the points in the bucket expire (`YYYY-MM-DD`)." }, "expiration_type": { "type": "string", "enum": [ "NO_EXPIRATION", "ROLLING_EXPIRATION", "CALENDAR_EXPIRATION", "SLIDING_EXPIRATION" ], "description": "Points expiration type." } }, "required": [ "id", "points", "expiration_date", "expiration_type" ] }, "RewardPurchaseCreateRequest": { "type": "object", "description": "Request body for purchasing a reward with points.", "properties": { "reward_id": { "type": "string", "description": "Identifier of the reward to purchase (format `lrew_...`)." }, "mode": { "type": "string", "enum": [ "TRANSACTION", "DRY_RUN" ], "default": "TRANSACTION", "description": "Purchase mode. `TRANSACTION` creates a PENDING reward transaction processed asynchronously (HTTP 202). `DRY_RUN` only simulates the purchase and returns the calculation result (HTTP 200); no transaction is created. Defaults to `TRANSACTION` when omitted." } }, "required": [ "reward_id" ], "additionalProperties": false }, "RewardPurchaseRefundRequest": { "type": "object", "description": "Request body for refunding a reward purchase. May be empty; defaults are applied.", "properties": { "policies": { "description": "Refund policies. When omitted or null, defaults are applied.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseRefundPolicies" }, { "type": "null" } ] } }, "additionalProperties": false }, "RewardPurchaseRefundPolicies": { "type": "object", "description": "Refund policies for a reward purchase refund.", "properties": { "refund": { "description": "Refund policy. `DEFAULT` applies the standard refund rules; `ALLOW` forces the refund to be allowed. Defaults to `DEFAULT`.", "oneOf": [ { "type": "string", "enum": [ "DEFAULT", "ALLOW" ] }, { "type": "null" } ] }, "stock": { "description": "Stock policy. `DEFAULT` returns the purchased quantity to the reward stock; `WRITE_OFF` does not return it. Defaults to `DEFAULT`.", "oneOf": [ { "type": "string", "enum": [ "DEFAULT", "WRITE_OFF" ] }, { "type": "null" } ] } }, "additionalProperties": false }, "RewardPurchaseTransaction": { "type": "object", "description": "A reward transaction. Represents a reward purchase or a reward refund.", "properties": { "id": { "type": "string", "description": "Unique reward transaction identifier (format `lrtx_...`). Absent for DRY_RUN (SIMULATED) transactions, which are never persisted." }, "card_id": { "type": "string", "description": "Identifier of the loyalty card the points were spent from (format `lcrd_...`)." }, "card_transaction_id": { "type": [ "string", "null" ], "description": "Identifier of the underlying card transaction (format `lctx_...`). `null` for DRY_RUN (SIMULATED) transactions." }, "program_id": { "type": "string", "description": "Identifier of the loyalty program (format `lprg_...`)." }, "member_id": { "type": "string", "description": "Identifier of the program member (format `lmbr_...`)." }, "reward_id": { "type": "string", "description": "Identifier of the purchased reward (format `lrew_...`)." }, "status": { "type": "string", "enum": [ "PENDING", "PROCESSING", "APPROVED", "REJECTED", "SIMULATED", "REFUNDED" ], "description": "Transaction status. `PENDING` — created, awaiting processing; `PROCESSING` — being processed; `APPROVED` — completed successfully; `REJECTED` — rejected (see `details.rejection`); `SIMULATED` — dry-run result, not persisted; `REFUNDED` — purchase has been refunded." }, "type": { "type": "string", "enum": [ "PURCHASE", "REFUND" ], "description": "Transaction type." }, "details": { "description": "Transaction details. Shape depends on `type` — purchase details for `PURCHASE`, refund details for `REFUND`.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseTransactionDetailsPurchase" }, { "$ref": "#/components/schemas/RewardPurchaseTransactionDetailsRefund" }, { "type": "null" } ] }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the transaction was created (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Timestamp when the transaction was last updated (ISO 8601), or `null`." }, "object": { "type": "string", "const": "reward_transaction", "description": "Object type marker. Always `reward_transaction`." } } }, "RewardPurchaseTransactionDetailsPurchase": { "type": "object", "description": "Details of a PURCHASE reward transaction.", "properties": { "reason": { "type": "string", "description": "Human-readable reason. For purchases: \"Points spent on reward\"." }, "rejection": { "description": "Rejection details, present when the transaction was rejected.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseRejection" }, { "type": "null" } ] }, "metadata": { "type": "object", "description": "Transaction metadata. Empty object when not set.", "additionalProperties": true }, "points": { "description": "Points spent on the purchase.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchasePoints" }, { "type": "null" } ] }, "result": { "description": "Fulfillment result, populated once the purchase is processed (APPROVED). `null` for PENDING/SIMULATED transactions.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseResult" }, { "type": "null" } ] } } }, "RewardPurchaseTransactionDetailsRefund": { "type": "object", "description": "Details of a REFUND reward transaction.", "properties": { "reason": { "type": "string", "description": "Human-readable reason, e.g. \"Reward refund — point purchase reversed\"." }, "rejection": { "description": "Rejection details, present when the transaction was rejected.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseRejection" }, { "type": "null" } ] }, "metadata": { "type": "object", "description": "Transaction metadata. Empty object when not set.", "additionalProperties": true }, "points": { "description": "Points returned by the refund.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchasePoints" }, { "type": "null" } ] }, "result": { "description": "Refunded reward result (what was reverted).", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseResult" }, { "type": "null" } ] }, "purchase": { "description": "References to the refunded purchase transactions.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseRefundPurchaseReference" }, { "type": "null" } ] } } }, "RewardPurchaseRefundPurchaseReference": { "type": "object", "description": "References to the original purchase transactions being refunded.", "properties": { "card_transaction": { "description": "Reference to the original card transaction.", "oneOf": [ { "type": "object", "properties": { "id": { "type": "string", "description": "Card transaction identifier (format `lctx_...`)." } } }, { "type": "null" } ] }, "reward_transaction": { "description": "Reference to the original reward transaction.", "oneOf": [ { "type": "object", "properties": { "id": { "type": "string", "description": "Reward transaction identifier (format `lrtx_...`)." } } }, { "type": "null" } ] } } }, "RewardPurchasePoints": { "type": "object", "description": "Points involved in the transaction.", "properties": { "total": { "type": "number", "description": "Total number of points." } } }, "RewardPurchaseRejection": { "type": "object", "description": "Rejection details.", "properties": { "reason": { "type": "string", "description": "Machine-readable rejection reason." }, "details": { "type": "string", "description": "Additional human-readable details about the rejection." } } }, "RewardPurchaseResult": { "type": "object", "description": "Reward fulfillment result. Contains the fulfilled reward reference, quantity and the material or digital fulfillment payload.", "properties": { "reward": { "description": "Reference to the fulfilled reward.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseResultReward" }, { "type": "null" } ] }, "quantity": { "type": [ "number", "null" ], "description": "Fulfilled quantity." }, "material": { "description": "Material reward fulfillment payload. Present for MATERIAL rewards.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseResultMaterial" }, { "type": "null" } ] }, "digital": { "description": "Digital reward fulfillment payload. Present for DIGITAL rewards.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseResultDigital" }, { "type": "null" } ] } } }, "RewardPurchaseResultReward": { "type": "object", "description": "Reference to the fulfilled reward.", "properties": { "id": { "type": "string", "description": "Reward identifier (format `lrew_...`)." }, "type": { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ], "description": "Reward type." } } }, "RewardPurchaseResultMaterial": { "type": "object", "description": "Material reward fulfillment.", "properties": { "type": { "type": "string", "enum": [ "PRODUCT", "SKU" ], "description": "Material reward type." }, "product": { "type": "object", "description": "Product payload (present when `type` is `PRODUCT`).", "additionalProperties": true }, "sku": { "type": "object", "description": "SKU payload (present when `type` is `SKU`).", "additionalProperties": true } } }, "RewardPurchaseResultDigital": { "type": "object", "description": "Digital reward fulfillment.", "properties": { "type": { "type": "string", "enum": [ "DISCOUNT_COUPONS", "GIFT_VOUCHERS", "LOYALTY_CARD_POINTS" ], "description": "Digital reward type." }, "discount_coupons": { "type": "array", "description": "Fulfilled discount coupons (present when `type` is `DISCOUNT_COUPONS`).", "items": { "$ref": "#/components/schemas/RewardPurchaseDigitalCoupon" } }, "gift_vouchers": { "type": "array", "description": "Fulfilled gift vouchers (present when `type` is `GIFT_VOUCHERS`).", "items": { "$ref": "#/components/schemas/RewardPurchaseDigitalGiftVoucher" } }, "loyalty_card_points": { "description": "Fulfilled loyalty card points (present when `type` is `LOYALTY_CARD_POINTS`).", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseDigitalLoyaltyCardPoints" }, { "type": "null" } ] } } }, "RewardPurchaseDigitalCoupon": { "type": "object", "description": "Discount coupon fulfillment entry.", "properties": { "id": { "type": "string", "description": "Voucher identifier of the coupon." }, "code": { "type": "string", "description": "Coupon code." }, "result": { "type": "string", "enum": [ "SKIPPED", "DELETED", "CREDITS_SUBTRACTED" ], "description": "Refund handling result for this coupon (present in refund results): `DELETED` — the coupon was deleted; `SKIPPED` — the coupon was left intact." } } }, "RewardPurchaseDigitalGiftVoucher": { "type": "object", "description": "Gift voucher fulfillment entry.", "properties": { "id": { "type": "string", "description": "Voucher identifier of the gift voucher." }, "code": { "type": "string", "description": "Gift voucher code." }, "amount": { "type": "number", "description": "Amount added to (or, for refunds, subtracted from) the gift voucher balance." }, "balance": { "type": "number", "description": "Gift voucher balance after the operation." }, "result": { "type": "string", "enum": [ "SKIPPED", "DELETED", "CREDITS_SUBTRACTED" ], "description": "Refund handling result for this gift voucher (present in refund results): `CREDITS_SUBTRACTED` — the credited balance was subtracted; `SKIPPED` — the voucher was left intact." } } }, "RewardPurchaseDigitalLoyaltyCardPoints": { "type": "object", "description": "Loyalty card points fulfillment entry.", "properties": { "points": { "type": "number", "description": "Number of points credited to the target loyalty card." }, "card_definition_id": { "type": "string", "description": "Target card definition identifier (format `lcdef_...`)." }, "card_id": { "type": "string", "description": "Target loyalty card identifier (format `lcrd_...`)." } } }, "RewardPurchaseCreateResponse": { "type": "object", "description": "Result of a reward purchase request.", "properties": { "transaction": { "description": "The created (or simulated) reward transaction.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseTransaction" }, { "type": "null" } ] }, "status": { "type": "string", "enum": [ "TRANSACTION_CREATED", "DRY_RUN" ], "description": "Result status. `TRANSACTION_CREATED` for `TRANSACTION` mode, `DRY_RUN` for dry-run mode." }, "message": { "type": "string", "description": "Human-readable result message. `TRANSACTION` mode: \"Reward purchase transaction created\". `DRY_RUN` mode: \"Dry run mode. No transaction was created. This is only a simulation.\"." } } }, "RewardPurchaseRefundResponse": { "type": "object", "description": "Result of a reward refund request.", "properties": { "transaction": { "description": "The created REFUND-type reward transaction.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseTransaction" }, { "type": "null" } ] }, "status": { "type": "string", "enum": [ "APPROVED" ], "description": "Result status. Always `APPROVED` on success." }, "message": { "type": "string", "description": "Human-readable result message: \"Reward refund transaction created. Points will be returned to the member's card shortly.\"." } } }, "RewardPurchaseListFilters": { "type": "object", "description": "Filters for listing reward purchases.", "properties": { "junction": { "description": "Logical junction between the field filters. Defaults to AND behavior.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by reward transaction id.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseFilterIdConditions" }, { "type": "null" } ] }, "reward_id": { "description": "Filter by reward id.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseFilterRewardIdConditions" }, { "type": "null" } ] }, "created_at": { "description": "Filter by creation date.", "oneOf": [ { "$ref": "#/components/schemas/RewardPurchaseFilterDateConditions" }, { "type": "null" } ] } }, "additionalProperties": false }, "RewardPurchaseFilterIdConditions": { "type": "object", "description": "ID filter conditions for reward transaction ids. Values must match pattern `^lrtx_[a-f0-9]+$`. `$is`/`$is_not` accept a single value (string or 1-element array); `$in`/`$not_in` accept a string or an array of 1-100 values.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches transactions whose id equals the given value.", "oneOf": [ { "type": "string", "pattern": "^lrtx_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lrtx_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Matches transactions whose id does not equal the given value.", "oneOf": [ { "type": "string", "pattern": "^lrtx_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lrtx_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Matches transactions whose id is one of the given values.", "oneOf": [ { "type": "string", "pattern": "^lrtx_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lrtx_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Matches transactions whose id is not one of the given values.", "oneOf": [ { "type": "string", "pattern": "^lrtx_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lrtx_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "RewardPurchaseFilterRewardIdConditions": { "type": "object", "description": "ID filter conditions for reward ids. Values must match pattern `^lrew_[a-f0-9]+$`. `$is`/`$is_not` accept a single value (string or 1-element array); `$in`/`$not_in` accept a string or an array of 1-100 values.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches transactions whose reward id equals the given value.", "oneOf": [ { "type": "string", "pattern": "^lrew_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Matches transactions whose reward id does not equal the given value.", "oneOf": [ { "type": "string", "pattern": "^lrew_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Matches transactions whose reward id is one of the given values.", "oneOf": [ { "type": "string", "pattern": "^lrew_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Matches transactions whose reward id is not one of the given values.", "oneOf": [ { "type": "string", "pattern": "^lrew_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "RewardPurchaseFilterDateConditions": { "$ref": "#/components/schemas/OrderPaymentFilterDateConditions" }, "OrderPaymentCreateRequest": { "type": "object", "description": "Request body for paying for an order with points.", "properties": { "card_id": { "type": "string", "description": "Identifier of the member's loyalty card to spend points from (format `lcrd_...`)." }, "order": { "$ref": "#/components/schemas/OrderPaymentOrder" }, "payment_limit": { "description": "Optional payment limit. When omitted, the default `CARD_BALANCE` limit is applied (spend up to the card balance).", "oneOf": [ { "$ref": "#/components/schemas/OrderPaymentLimit" }, { "type": "null" } ] }, "mode": { "description": "Payment mode. `TRANSACTION` creates a PENDING order transaction processed asynchronously (HTTP 202). `DRY_RUN` only simulates the payment and returns the calculation result (HTTP 200); no transaction is created. Defaults to `TRANSACTION` when omitted or null.", "oneOf": [ { "type": "string", "enum": [ "TRANSACTION", "DRY_RUN" ] }, { "type": "null" } ] } }, "required": [ "card_id", "order" ], "additionalProperties": false }, "OrderPaymentOrder": { "type": "object", "description": "Reference to the order being paid. At least one of `id` or `source_id` must be provided.", "properties": { "id": { "description": "Voucherify order identifier.", "oneOf": [ { "type": "string", "pattern": "^ord_[a-f0-9]+$" }, { "type": "null" } ] }, "source_id": { "description": "External (source) order identifier.", "oneOf": [ { "type": "string", "minLength": 1 }, { "type": "null" } ] } }, "additionalProperties": false }, "OrderPaymentLimit": { "type": "object", "description": "Payment limit. Discriminated by `type`: `CARD_BALANCE` — spend up to the card balance (no additional properties required); `POINTS_LIMIT` — cap the number of points spent (requires `points_limit`); `AMOUNT_LIMIT` — cap the paid amount (requires `amount_limit`).", "properties": { "type": { "type": "string", "enum": [ "CARD_BALANCE", "POINTS_LIMIT", "AMOUNT_LIMIT" ], "description": "Payment limit type." }, "points_limit": { "description": "Maximum number of points to spend. Required when `type` is `POINTS_LIMIT`.", "oneOf": [ { "$ref": "#/components/schemas/OrderPaymentLimitDefinition" }, { "type": "null" } ] }, "amount_limit": { "description": "Maximum amount to pay. Required when `type` is `AMOUNT_LIMIT`.", "oneOf": [ { "$ref": "#/components/schemas/OrderPaymentLimitDefinition" }, { "type": "null" } ] } }, "required": [ "type" ], "additionalProperties": false, "oneOf": [ { "properties": { "type": { "const": "CARD_BALANCE" } } }, { "required": [ "points_limit" ], "properties": { "type": { "const": "POINTS_LIMIT" }, "points_limit": { "$ref": "#/components/schemas/OrderPaymentLimitDefinition" } } }, { "required": [ "amount_limit" ], "properties": { "type": { "const": "AMOUNT_LIMIT" }, "amount_limit": { "$ref": "#/components/schemas/OrderPaymentLimitDefinition" } } } ] }, "OrderPaymentLimitDefinition": { "type": "object", "description": "Definition of a payment limit value.", "properties": { "max": { "type": "integer", "minimum": 1, "description": "Maximum value of the limit." } }, "required": [ "max" ], "additionalProperties": false }, "OrderPaymentTransaction": { "type": "object", "description": "An order transaction. Represents a pay-with-points payment.", "properties": { "id": { "type": "string", "description": "Unique order transaction identifier (format `lotx_...`). Absent for DRY_RUN (SIMULATED) transactions, which are never persisted." }, "program_id": { "type": "string", "description": "Identifier of the loyalty program (format `lprg_...`)." }, "member_id": { "type": "string", "description": "Identifier of the program member (format `lmbr_...`)." }, "card_id": { "type": "string", "description": "Identifier of the loyalty card the points were spent from (format `lcrd_...`)." }, "card_definition_id": { "type": "string", "description": "Identifier of the card definition (format `lcdef_...`)." }, "card_transaction_id": { "type": [ "string", "null" ], "description": "Identifier of the underlying card transaction (format `lctx_...`). `null` for DRY_RUN (SIMULATED) transactions." }, "order_id": { "type": "string", "description": "Identifier of the paid order (format `ord_...`)." }, "status": { "type": "string", "enum": [ "PENDING", "PROCESSING", "APPROVED", "REJECTED", "SIMULATED" ], "description": "Transaction status. `PENDING` — created, awaiting processing; `PROCESSING` — being processed; `APPROVED` — completed successfully; `REJECTED` — rejected (see `details.rejection`); `SIMULATED` — dry-run result, not persisted." }, "type": { "type": "string", "enum": [ "PAY_WITH_POINTS" ], "description": "Transaction type." }, "details": { "description": "Transaction details for the `PAY_WITH_POINTS` type.", "oneOf": [ { "$ref": "#/components/schemas/OrderPaymentTransactionDetails" }, { "type": "null" } ] }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the transaction was created (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Timestamp when the transaction was last updated (ISO 8601), or `null`." }, "object": { "type": "string", "const": "order_transaction", "description": "Object type marker. Always `order_transaction`." } } }, "OrderPaymentTransactionDetails": { "type": "object", "description": "Details of a PAY_WITH_POINTS order transaction.", "properties": { "reason": { "type": "string", "description": "Human-readable reason: \"Points spent on order payment\"." }, "rejection": { "description": "Rejection details, present when the transaction was rejected.", "oneOf": [ { "$ref": "#/components/schemas/OrderPaymentRejection" }, { "type": "null" } ] }, "metadata": { "type": "object", "description": "Transaction metadata. For pay-with-points transactions this contains the flattened payment limits used for the calculation: `amount_limit` and/or `points_limit` (omitted when the default CARD_BALANCE limit was used). Empty object when not set.", "properties": { "amount_limit": { "type": "integer", "description": "Maximum amount limit applied to the payment (if any)." }, "points_limit": { "type": "integer", "description": "Maximum points limit applied to the payment (if any)." } }, "additionalProperties": true }, "payment": { "$ref": "#/components/schemas/OrderPaymentPaymentDetails" } } }, "OrderPaymentPaymentDetails": { "type": "object", "description": "Payment calculation details.", "properties": { "id": { "type": "string", "description": "Payment identifier. Omitted when not set." }, "amount": { "type": "number", "description": "Order amount paid with points." }, "points_spent": { "type": "number", "description": "Number of points spent on the payment." }, "exchange_ratio": { "type": "number", "description": "Points-to-amount exchange ratio evaluated from the card definition's pay-with-points formula." } } }, "OrderPaymentRejection": { "type": "object", "description": "Rejection details.", "properties": { "reason": { "type": "string", "description": "Machine-readable rejection reason." }, "details": { "type": "string", "description": "Additional human-readable details about the rejection." } } }, "OrderPaymentCreateResponse": { "type": "object", "description": "Result of a pay-with-points request.", "properties": { "transaction": { "description": "The created (or simulated) order transaction.", "oneOf": [ { "$ref": "#/components/schemas/OrderPaymentTransaction" }, { "type": "null" } ] }, "status": { "type": "string", "enum": [ "TRANSACTION_CREATED", "DRY_RUN" ], "description": "Result status. `TRANSACTION_CREATED` for `TRANSACTION` mode, `DRY_RUN` for dry-run mode." }, "message": { "type": "string", "description": "Human-readable result message. `TRANSACTION` mode: \"Pay with points transaction created\". `DRY_RUN` mode: \"Dry run mode. No transaction was created. This is only a simulation.\"." } } }, "OrderPaymentListFilters": { "type": "object", "description": "Filters for listing order payments.", "properties": { "junction": { "description": "Logical junction between the field filters. Defaults to AND behavior.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by order transaction id.", "oneOf": [ { "$ref": "#/components/schemas/OrderPaymentFilterIdConditions" }, { "type": "null" } ] }, "created_at": { "description": "Filter by creation date.", "oneOf": [ { "$ref": "#/components/schemas/OrderPaymentFilterDateConditions" }, { "type": "null" } ] } }, "additionalProperties": false }, "OrderPaymentFilterIdConditions": { "type": "object", "description": "ID filter conditions for order transaction ids. Values must match pattern `^lotx_[a-f0-9]+$`. `$is`/`$is_not` accept a single value (string or 1-element array); `$in`/`$not_in` accept a string or an array of 1-100 values.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches transactions whose id equals the given value.", "oneOf": [ { "type": "string", "pattern": "^lotx_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lotx_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Matches transactions whose id does not equal the given value.", "oneOf": [ { "type": "string", "pattern": "^lotx_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lotx_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Matches transactions whose id is one of the given values.", "oneOf": [ { "type": "string", "pattern": "^lotx_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lotx_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Matches transactions whose id is not one of the given values.", "oneOf": [ { "type": "string", "pattern": "^lotx_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lotx_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "OrderPaymentFilterDateConditions": { "type": "object", "description": "Date filter conditions. `$before`/`$after` accept an ISO date-time string. `$is`/`$more_than`/`$less_than` accept a non-negative integer number of days ago. `$has_value`/`$is_unknown` accept any single value and match rows where the field is set / not set. Single values may also be passed as 1-element arrays.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$before": { "description": "Matches rows with the date before the given date-time.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$after": { "description": "Matches rows with the date after the given date-time.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is": { "description": "Matches rows with the date exactly the given number of days ago.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$more_than": { "description": "Matches rows with the date more than the given number of days ago.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$less_than": { "description": "Matches rows with the date less than the given number of days ago.", "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$has_value": { "description": "Matches rows where the date field is set.", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] }, "$is_unknown": { "description": "Matches rows where the date field is not set.", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "BenefitTransaction": { "type": "object", "description": "A benefit transaction. Represents a benefit fulfillment.", "properties": { "id": { "type": "string", "description": "Unique benefit transaction identifier (format `lbtx_...`)." }, "benefit_id": { "type": "string", "description": "Identifier of the fulfilled benefit (format `lben_...`)." }, "program_id": { "type": "string", "description": "Identifier of the loyalty program (format `lprg_...`)." }, "member_id": { "type": "string", "description": "Identifier of the program member (format `lmbr_...`)." }, "earning_rule_id": { "type": "string", "description": "Identifier of the earning rule that triggered the fulfillment (format `lern_...`)." }, "type": { "type": "string", "enum": [ "FULFILLMENT" ], "description": "Transaction type." }, "details": { "description": "Transaction details for the `FULFILLMENT` type.", "oneOf": [ { "$ref": "#/components/schemas/BenefitTransactionDetails" }, { "type": "null" } ] }, "status": { "type": "string", "enum": [ "PENDING", "APPROVED", "REJECTED" ], "description": "Transaction status. `PENDING` — created, awaiting processing; `APPROVED` — completed successfully; `REJECTED` — rejected (see `details.rejection`)." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the transaction was created (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Timestamp when the transaction was last updated (ISO 8601), or `null`." }, "object": { "type": "string", "const": "benefit_transaction", "description": "Object type marker. Always `benefit_transaction`." } } }, "BenefitTransactionDetails": { "type": "object", "description": "Details of a FULFILLMENT benefit transaction.", "properties": { "reason": { "type": "string", "description": "Human-readable reason for the fulfillment." }, "rejection": { "description": "Rejection details, present when the transaction was rejected.", "oneOf": [ { "$ref": "#/components/schemas/BenefitTransactionRejection" }, { "type": "null" } ] }, "metadata": { "type": "object", "description": "Transaction metadata. Empty object when not set.", "additionalProperties": true }, "result": { "description": "Fulfillment result payload, or `null` when not yet available.", "oneOf": [ { "type": "object", "additionalProperties": true }, { "type": "null" } ] } } }, "BenefitTransactionRejection": { "type": "object", "description": "Rejection details.", "properties": { "reason": { "type": "string", "description": "Machine-readable rejection reason." }, "details": { "type": "string", "description": "Additional human-readable details about the rejection." } } }, "BenefitTransactionListFilters": { "type": "object", "description": "Filters for listing benefit transactions.", "properties": { "junction": { "description": "Logical junction between the field filters. Defaults to AND behavior.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "benefit_id": { "description": "Filter by benefit id.", "oneOf": [ { "$ref": "#/components/schemas/BenefitTransactionFilterBenefitIdConditions" }, { "type": "null" } ] }, "created_at": { "description": "Filter by creation date.", "oneOf": [ { "$ref": "#/components/schemas/OrderPaymentFilterDateConditions" }, { "type": "null" } ] } }, "additionalProperties": false }, "BenefitTransactionFilterBenefitIdConditions": { "type": "object", "description": "ID filter conditions for benefit ids. Values must match pattern `^lben_[a-f0-9]+$`. `$is`/`$is_not` accept a single value (string or 1-element array); `$in`/`$not_in` accept a string or an array of 1-100 values.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches transactions whose benefit id equals the given value.", "oneOf": [ { "type": "string", "pattern": "^lben_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lben_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Matches transactions whose benefit id does not equal the given value.", "oneOf": [ { "type": "string", "pattern": "^lben_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lben_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Matches transactions whose benefit id is one of the given values.", "oneOf": [ { "type": "string", "pattern": "^lben_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lben_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Matches transactions whose benefit id is not one of the given values.", "oneOf": [ { "type": "string", "pattern": "^lben_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lben_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "TierTransaction": { "type": "object", "description": "A tier transaction. Represents a tier membership change.", "properties": { "id": { "type": "string", "description": "Unique tier transaction identifier (format `lttx_...`)." }, "card_id": { "type": "string", "description": "Identifier of the related loyalty card (format `lcrd_...`)." }, "program_id": { "type": "string", "description": "Identifier of the loyalty program (format `lprg_...`)." }, "member_id": { "type": "string", "description": "Identifier of the program member (format `lmbr_...`)." }, "card_definition_id": { "type": "string", "description": "Identifier of the card definition (format `lcdef_...`)." }, "tier_structure_id": { "type": "string", "description": "Identifier of the tier structure (format `lts_...`)." }, "tier_id": { "type": [ "string", "null" ], "description": "Identifier of the related tier (format `lt_...`), or `null`." }, "type": { "type": "string", "enum": [ "UPGRADED", "DOWNGRADED", "JOINED", "LEFT", "PROLONGED" ], "description": "Transaction type. `JOINED` — member joined a tier; `LEFT` — member left a tier; `UPGRADED` — member moved to a higher tier; `DOWNGRADED` — member moved to a lower tier; `PROLONGED` — the member's tier membership was prolonged." }, "details": { "$ref": "#/components/schemas/TierTransactionDetails" }, "status": { "type": "string", "enum": [ "PENDING", "APPROVED", "REJECTED" ], "description": "Transaction status. `PENDING` — created, awaiting processing; `APPROVED` — completed successfully; `REJECTED` — rejected (see `details.rejection`)." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the transaction was created (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Timestamp when the transaction was last updated (ISO 8601), or `null`." }, "object": { "type": "string", "const": "tier_transaction", "description": "Object type marker. Always `tier_transaction`." } } }, "TierTransactionDetails": { "type": "object", "description": "Tier transaction details. All fields are nullable; which fields are populated depends on the transaction type: `JOINED`/`PROLONGED` — `tier_to`, `start_at`, `expires_at` (no `tier_from`); `LEFT` — `tier_from` (no `tier_to`); `UPGRADED`/`DOWNGRADED` — both `tier_from` and `tier_to`.", "properties": { "points": { "type": [ "number", "null" ], "description": "Points balance relevant to the tier change, or `null`." }, "tier_from": { "type": [ "string", "null" ], "description": "Identifier of the tier the member moved from (format `lt_...`). `null` for `JOINED` and `PROLONGED` transactions." }, "tier_to": { "type": [ "string", "null" ], "description": "Identifier of the tier the member moved to (format `lt_...`). `null` for `LEFT` transactions." }, "origin": { "description": "What triggered the tier change.", "oneOf": [ { "$ref": "#/components/schemas/TierTransactionOrigin" }, { "type": "null" } ] }, "rejection": { "description": "Rejection details, present when the transaction was rejected. Known rejection reason: `SUPERSEDED_BY_LATER_TRANSACTION`.", "oneOf": [ { "$ref": "#/components/schemas/TierTransactionRejection" }, { "type": "null" } ] }, "start_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Start of the tier membership period, or `null`." }, "expires_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Expiration of the tier membership period, or `null`." } } }, "TierTransactionOrigin": { "type": "object", "description": "Origin of the tier change.", "properties": { "type": { "type": "string", "enum": [ "card_operations", "daily_task_operations", "member_card_created", "member_card_deleted" ], "description": "Origin type. `card_operations` — triggered by card point operations; `daily_task_operations` — triggered by scheduled daily tasks; `member_card_created` — triggered by creating a member card; `member_card_deleted` — triggered by deleting a member card." }, "card_transaction_ids": { "type": "array", "items": { "type": "string" }, "description": "Identifiers of the card transactions that triggered the tier change (format `lctx_...`)." } } }, "TierTransactionRejection": { "type": "object", "description": "Rejection details.", "properties": { "reason": { "type": "string", "description": "Machine-readable rejection reason. Known value: `SUPERSEDED_BY_LATER_TRANSACTION`." }, "details": { "type": "string", "description": "Additional human-readable details about the rejection." } } }, "TierTransactionListFilters": { "type": "object", "description": "Filters for listing tier transactions.", "properties": { "junction": { "description": "Logical junction between the field filters. Defaults to AND behavior.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "card_id": { "description": "Filter by loyalty card id.", "oneOf": [ { "$ref": "#/components/schemas/TierTransactionFilterCardIdConditions" }, { "type": "null" } ] }, "created_at": { "description": "Filter by creation date.", "oneOf": [ { "$ref": "#/components/schemas/OrderPaymentFilterDateConditions" }, { "type": "null" } ] } }, "additionalProperties": false }, "TierTransactionFilterCardIdConditions": { "type": "object", "description": "ID filter conditions for loyalty card ids. Values must match pattern `^lcrd_[a-f0-9]+$`. `$is`/`$is_not` accept a single value (string or 1-element array); `$in`/`$not_in` accept a string or an array of 1-100 values.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches transactions whose card id equals the given value.", "oneOf": [ { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Matches transactions whose card id does not equal the given value.", "oneOf": [ { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Matches transactions whose card id is one of the given values.", "oneOf": [ { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Matches transactions whose card id is not one of the given values.", "oneOf": [ { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lcrd_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "RewardPurchaseListResponse": { "type": "object", "description": "Paginated list of reward purchase transactions.", "properties": { "data": { "type": "array", "description": "Reward purchase transactions (type `PURCHASE` only).", "items": { "$ref": "#/components/schemas/RewardPurchaseTransaction" } }, "cursor": { "description": "Pagination cursor. `null` when there are no more results.", "oneOf": [ { "type": "object", "properties": { "next": { "type": "string", "description": "Cursor to pass as the `cursor` query parameter to fetch the next page (format `lcrstrx_...`)." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp when the cursor expires." } } }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type marker. Always `list`." } } }, "OrderPaymentListResponse": { "type": "object", "description": "Paginated list of order payment transactions.", "properties": { "data": { "type": "array", "description": "Order payment transactions.", "items": { "$ref": "#/components/schemas/OrderPaymentTransaction" } }, "cursor": { "description": "Pagination cursor. `null` when there are no more results.", "oneOf": [ { "type": "object", "properties": { "next": { "type": "string", "description": "Cursor to pass as the `cursor` query parameter to fetch the next page (format `lcrsotx_...`)." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp when the cursor expires." } } }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type marker. Always `list`." } } }, "BenefitTransactionListResponse": { "type": "object", "description": "Paginated list of benefit transactions.", "properties": { "data": { "type": "array", "description": "Benefit transactions.", "items": { "$ref": "#/components/schemas/BenefitTransaction" } }, "cursor": { "description": "Pagination cursor. `null` when there are no more results.", "oneOf": [ { "type": "object", "properties": { "next": { "type": "string", "description": "Cursor to pass as the `cursor` query parameter to fetch the next page (format `lcrsbtx_...`)." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp when the cursor expires." } } }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type marker. Always `list`." } } }, "TierTransactionListResponse": { "type": "object", "description": "Paginated list of tier transactions.", "properties": { "data": { "type": "array", "description": "Tier transactions.", "items": { "$ref": "#/components/schemas/TierTransaction" } }, "cursor": { "description": "Pagination cursor. `null` when there are no more results.", "oneOf": [ { "type": "object", "properties": { "next": { "type": "string", "description": "Cursor to pass as the `cursor` query parameter to fetch the next page (format `lcrsttx_...`)." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp when the cursor expires." } } }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type marker. Always `list`." } } }, "CardDailyReportEntry": { "type": "object", "description": "Aggregated daily card points statistics for one period. All numeric fields default to 0.", "properties": { "date": { "type": "string", "format": "date", "description": "Date of the aggregation period (`YYYY-MM-DD`)." }, "points_total": { "type": "number", "description": "Total points balance change in the period." }, "points_earned": { "type": "number", "description": "Points earned in the period." }, "points_added": { "type": "number", "description": "Points added manually in the period." }, "points_purchased": { "type": "number", "description": "Points purchased (e.g. via loyalty-card-points rewards) in the period." }, "points_purchased_reversed": { "type": "number", "description": "Purchased points reversed (e.g. by reward refunds) in the period." }, "points_subtracted": { "type": "number", "description": "Points subtracted manually in the period." }, "points_expired": { "type": "number", "description": "Points expired in the period." }, "points_spent": { "type": "number", "description": "Points spent (on rewards and order payments) in the period." }, "points_refunded": { "type": "number", "description": "Points refunded in the period." }, "points_returned": { "type": "number", "description": "Points returned in the period." }, "points_locked": { "type": "number", "description": "Points locked in the period." }, "points_unlocked": { "type": "number", "description": "Points unlocked in the period." }, "pending_points_total": { "type": "number", "description": "Total pending points change in the period." }, "pending_points_activated": { "type": "number", "description": "Pending points activated in the period." }, "pending_points_canceled": { "type": "number", "description": "Pending points canceled in the period." }, "object": { "type": "string", "const": "card_daily_report", "description": "Object type marker. Always `card_daily_report`." } } }, "CardDailyReportResponse": { "type": "object", "description": "Card daily report result.", "properties": { "data": { "type": "array", "description": "Report entries, one per aggregation period.", "items": { "$ref": "#/components/schemas/CardDailyReportEntry" } }, "object": { "type": "string", "const": "report", "description": "Object type marker. Always `report`." } } }, "SpendingReportDailyEntry": { "type": "object", "description": "Aggregated daily program spending statistics for one period and card definition. All numeric fields default to 0.", "properties": { "date": { "type": "string", "format": "date", "description": "Date of the aggregation period (`YYYY-MM-DD`)." }, "card_definition_id": { "type": "string", "description": "Identifier of the card definition (format `lcdef_...`)." }, "success": { "type": "number", "description": "Number of successful spending operations in the period." }, "success_on_reward": { "type": "number", "description": "Number of successful reward purchases in the period." }, "success_on_order": { "type": "number", "description": "Number of successful order payments in the period." }, "points": { "type": "number", "description": "Total points spent in the period." }, "points_on_rewards": { "type": "number", "description": "Points spent on reward purchases in the period." }, "points_on_order": { "type": "number", "description": "Points spent on order payments in the period." }, "amount_on_order": { "type": "number", "description": "Order amount paid with points in the period." }, "object": { "type": "string", "const": "spending_daily_report", "description": "Object type marker. Always `spending_daily_report`." } } }, "SpendingReportSummaryEntry": { "type": "object", "description": "Total program spending statistics for one card definition. All numeric fields default to 0.", "properties": { "id": { "type": "string", "description": "Identifier of the summary row." }, "card_definition_id": { "type": "string", "description": "Identifier of the card definition (format `lcdef_...`)." }, "success": { "type": "number", "description": "Total number of successful spending operations." }, "success_on_reward": { "type": "number", "description": "Total number of successful reward purchases." }, "success_on_order": { "type": "number", "description": "Total number of successful order payments." }, "points": { "type": "number", "description": "Total points spent." }, "points_on_rewards": { "type": "number", "description": "Total points spent on reward purchases." }, "points_on_order": { "type": "number", "description": "Total points spent on order payments." }, "amount_on_order": { "type": "number", "description": "Total order amount paid with points." }, "object": { "type": "string", "const": "spending_summary_report", "description": "Object type marker. Always `spending_summary_report`." } } }, "SpendingReportDailyResponse": { "type": "object", "description": "Program spending daily report result.", "properties": { "data": { "type": "array", "description": "Report entries, one per aggregation period and card definition.", "items": { "$ref": "#/components/schemas/SpendingReportDailyEntry" } }, "object": { "type": "string", "const": "report", "description": "Object type marker. Always `report`." } } }, "SpendingReportSummaryResponse": { "type": "object", "description": "Program spending summary report result.", "properties": { "data": { "type": "array", "description": "Report entries, one per card definition.", "items": { "$ref": "#/components/schemas/SpendingReportSummaryEntry" } }, "object": { "type": "string", "const": "report", "description": "Object type marker. Always `report`." } } }, "SpendingReportListFilters": { "type": "object", "description": "Filters for spending reports.", "properties": { "junction": { "description": "Logical junction between the field filters. Defaults to AND behavior.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "card_definition_id": { "description": "Filter by card definition id.", "oneOf": [ { "$ref": "#/components/schemas/SpendingReportFilterCardDefinitionIdConditions" }, { "type": "null" } ] } }, "additionalProperties": false }, "SpendingReportFilterCardDefinitionIdConditions": { "type": "object", "description": "ID filter conditions for card definition ids. Values must match pattern `^lcdef_[a-f0-9]+$`. `$is`/`$is_not` accept a single value (string or 1-element array); `$in`/`$not_in` accept a string or an array of 1-100 values.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches rows whose card definition id equals the given value.", "oneOf": [ { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$is_not": { "description": "Matches rows whose card definition id does not equal the given value.", "oneOf": [ { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 }, { "type": "null" } ] }, "$in": { "description": "Matches rows whose card definition id is one of the given values.", "oneOf": [ { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] }, "$not_in": { "description": "Matches rows whose card definition id is not one of the given values.", "oneOf": [ { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "CardDefinitionCreateRequest": { "type": "object", "description": "Request body for creating a card definition.\nCross-field rules apply: `balance_settings.allow_negative: true` requires\n`points_expiration.type` to be `NO_EXPIRATION`; the earned points refund mode\n`REVOKE_BELOW_ZERO` requires `allow_negative: true`; and the earned points refund\nmethod `REVOKE_FROM_PENDING` requires `pending_points.type` to be `PERIOD_BASED`,\n`FIXED_DATES` or `EVENT_BASED`.", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Card definition name." }, "type": { "type": "string", "enum": [ "INDIVIDUAL" ], "description": "Card definition type. Currently only `INDIVIDUAL` is supported." }, "status": { "type": [ "string", "null" ], "enum": [ "DRAFT", "ACTIVE", null ], "description": "Initial status. Allowed values on create are `DRAFT` and `ACTIVE`. Defaults to `DRAFT` when omitted." }, "code_config": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionCodeConfigInput" }, { "type": "null" } ], "description": "Card code generation configuration. Defaults to a 10-character alphanumeric pattern." }, "points_expiration": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPointsExpirationInput" }, { "type": "null" } ], "description": "Points expiration policy. Defaults to `NO_EXPIRATION`." }, "pending_points": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPendingPointsInput" }, { "type": "null" } ], "description": "Pending points activation policy. Defaults to `IMMEDIATE`." }, "earning_limits": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionEarningLimitsInput" }, { "type": "null" } ], "description": "Points earning limits. Defaults to `NO_LIMIT` for both global and transaction limits." }, "spending_limits": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsInput" }, { "type": "null" } ], "description": "Points spending limits. Defaults to `NO_LIMIT` for both global and transaction limits." }, "refunds": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionRefundsInput" }, { "type": "null" } ], "description": "Refund handling configuration. Defaults to `NONE` for both spent and earned points." }, "balance_settings": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionBalanceSettingsInput" }, { "type": "null" } ], "description": "Card balance settings. Defaults to `allow_negative: false`." }, "pay_with_points": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPayWithPointsInput" }, { "type": "null" } ], "description": "Pay-with-points configuration. Defaults to `NO_PAYMENTS`." }, "metadata": { "type": [ "object", "null" ], "description": "Arbitrary key-value metadata attached to the card definition." } }, "required": [ "name", "type" ], "additionalProperties": false }, "CardDefinitionUpdateRequest": { "type": "object", "description": "Request body for updating a card definition.\nAll properties are optional. `type` and `status` cannot be updated.", "properties": { "name": { "type": [ "string", "null" ], "minLength": 1, "maxLength": 200, "description": "Card definition name." }, "code_config": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionCodeConfigInput" }, { "type": "null" } ], "description": "Card code generation configuration." }, "points_expiration": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPointsExpirationInput" }, { "type": "null" } ], "description": "Points expiration policy." }, "pending_points": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPendingPointsInput" }, { "type": "null" } ], "description": "Pending points activation policy." }, "earning_limits": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionEarningLimitsInput" }, { "type": "null" } ], "description": "Points earning limits." }, "spending_limits": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsInput" }, { "type": "null" } ], "description": "Points spending limits." }, "refunds": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionRefundsInput" }, { "type": "null" } ], "description": "Refund handling configuration." }, "balance_settings": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionBalanceSettingsInput" }, { "type": "null" } ], "description": "Card balance settings." }, "pay_with_points": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPayWithPointsInput" }, { "type": "null" } ], "description": "Pay-with-points configuration." }, "metadata": { "type": [ "object", "null" ], "description": "Arbitrary key-value metadata attached to the card definition." } }, "additionalProperties": false }, "CardDefinitionCodeConfigInput": { "type": "object", "description": "Card code generation configuration.\nWhen `pattern` is provided, the effective code length is the number of `#`\nplaceholders in the pattern; otherwise `length` (default 10) `#` placeholders are used.", "properties": { "length": { "type": [ "integer", "null" ], "description": "Number of generated characters in the code (ignored when `pattern` is provided).\nA positive integer. Defaults to 10." }, "charset": { "type": [ "string", "null" ], "description": "Characters used for code generation. Defaults to alphanumeric: `0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`." }, "prefix": { "type": [ "string", "null" ], "description": "Fixed prefix prepended to every generated code. Defaults to an empty string." }, "postfix": { "type": [ "string", "null" ], "description": "Fixed postfix appended to every generated code. Defaults to an empty string." }, "pattern": { "type": [ "string", "null" ], "description": "Code pattern where each `#` is replaced with a random character from the charset, e.g. `###-###`. Defaults to `#` repeated `length` times." } }, "additionalProperties": false }, "CardDefinitionPointsExpirationInput": { "type": "object", "description": "Points expiration policy.\nConditional requirements based on `type`:\n- `NO_EXPIRATION`: `rolling_expiration`, `calendar_expiration` and `sliding_expiration` must be null/absent.\n- `ROLLING_EXPIRATION`: `rolling_expiration` is required; the other two must be null/absent.\n- `CALENDAR_EXPIRATION`: `calendar_expiration` is required; the other two must be null/absent.\n- `SLIDING_EXPIRATION`: `sliding_expiration` is required; the other two must be null/absent.", "properties": { "type": { "type": "string", "enum": [ "NO_EXPIRATION", "ROLLING_EXPIRATION", "CALENDAR_EXPIRATION", "SLIDING_EXPIRATION" ], "description": "Points expiration type." }, "rolling_expiration": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPointsExpirationRollingExpirationInput" }, { "type": "null" } ], "description": "Rolling expiration configuration. Required when `type` is `ROLLING_EXPIRATION`, must be null otherwise." }, "calendar_expiration": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPointsExpirationCalendarExpirationInput" }, { "type": "null" } ], "description": "Calendar expiration configuration. Required when `type` is `CALENDAR_EXPIRATION`, must be null otherwise." }, "sliding_expiration": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPointsExpirationSlidingExpirationInput" }, { "type": "null" } ], "description": "Sliding expiration configuration. Required when `type` is `SLIDING_EXPIRATION`, must be null otherwise." } }, "required": [ "type" ], "additionalProperties": false }, "CardDefinitionPointsExpirationRollingExpirationInput": { "type": "object", "description": "Rolling expiration configuration - points expire after a fixed period from earning.", "properties": { "period": { "$ref": "#/components/schemas/CardDefinitionPointsExpirationRollingExpirationPeriodInput" }, "rounding": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPointsExpirationRollingExpirationRoundingInput" }, { "type": "null" } ], "description": "Optional rounding applied to the calculated expiration date." } }, "required": [ "period" ], "additionalProperties": false }, "CardDefinitionPointsExpirationRollingExpirationPeriodInput": { "type": "object", "description": "Rolling expiration period. The maximum `value` depends on `unit`:\n1-90 for `DAY`, 1-12 for `MONTH`, 1-5 for `YEAR` (enforced via if/then conditions).", "properties": { "unit": { "type": "string", "enum": [ "DAY", "MONTH", "YEAR" ], "description": "Period unit." }, "value": { "type": "integer", "minimum": 1, "maximum": 90, "description": "Period length. Maximum: 90 for `DAY`, 12 for `MONTH`, 5 for `YEAR`." } }, "required": [ "unit", "value" ], "additionalProperties": false }, "CardDefinitionPointsExpirationRollingExpirationRoundingInput": { "type": "object", "description": "Rounding of the rolling expiration date. When `type` is `END_OF_PARTICULAR_MONTH`,\n`value` (month number 1-12) is required; for all other types `value` must be null/absent.", "properties": { "type": { "type": "string", "enum": [ "END_OF_MONTH", "END_OF_QUARTER", "END_OF_HALF_YEAR", "END_OF_YEAR", "END_OF_PARTICULAR_MONTH" ], "description": "Rounding type." }, "value": { "type": [ "integer", "null" ], "minimum": 1, "maximum": 12, "description": "Month number (1-12). Required when `type` is `END_OF_PARTICULAR_MONTH`, must be null otherwise." } }, "required": [ "type" ], "additionalProperties": false }, "CardDefinitionPointsExpirationCalendarExpirationInput": { "type": "object", "description": "Calendar expiration configuration - points expire on fixed calendar dates.", "properties": { "expiration_dates": { "type": "array", "items": { "$ref": "#/components/schemas/CardDefinitionPointsExpirationCalendarExpirationDateInput" }, "minItems": 1, "maxItems": 20, "description": "List of calendar dates on which points expire (1-20 dates)." } }, "required": [ "expiration_dates" ], "additionalProperties": false }, "CardDefinitionPointsExpirationCalendarExpirationDateInput": { "type": "object", "description": "A calendar date (day + month). The maximum `day` depends on `month`\n(enforced via if/then conditions): 29 for February, 30 for April/June/September/November,\n31 for the remaining months.", "properties": { "day": { "type": "integer", "minimum": 1, "maximum": 31, "description": "Day of the month. Maximum depends on the month: 29 for February, 30 for April, June, September, November, 31 otherwise." }, "month": { "type": "integer", "minimum": 1, "maximum": 12, "description": "Month number (1-12)." } }, "required": [ "day", "month" ], "additionalProperties": false }, "CardDefinitionPointsExpirationSlidingExpirationInput": { "type": "object", "description": "Sliding expiration configuration - points expiration slides on member activity.\nAt least one of `earning_activity`, `spending_activity` or `custom_activity` must be `true`.\nWhen `custom_activity` is `true`, `custom_activity_types` is required with 1-10 unique\ncustom event schema IDs.", "properties": { "earning_activity": { "type": "boolean", "description": "Whether earning points resets the expiration window." }, "spending_activity": { "type": "boolean", "description": "Whether spending points resets the expiration window." }, "custom_activity": { "type": "boolean", "description": "Whether the configured custom events reset the expiration window." }, "custom_activity_types": { "type": [ "array", "null" ], "items": { "type": "string", "pattern": "^ms_[a-zA-Z0-9]+" }, "maxItems": 10, "description": "Custom event schema IDs (pattern `^ms_[a-zA-Z0-9]+`) that reset the expiration window.\nRequired with 1-10 unique items when `custom_activity` is `true`." }, "period": { "$ref": "#/components/schemas/CardDefinitionPointsExpirationSlidingExpirationPeriodInput" } }, "required": [ "period" ], "additionalProperties": false }, "CardDefinitionPointsExpirationSlidingExpirationPeriodInput": { "type": "object", "description": "Sliding expiration period. The maximum `value` depends on `unit`:\n1-90 for `DAY`, 1-12 for `MONTH`, 1-1 for `YEAR` (enforced via if/then conditions).", "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 90, "description": "Period length. Maximum: 90 for `DAY`, 12 for `MONTH`, 1 for `YEAR`." }, "unit": { "type": "string", "enum": [ "DAY", "MONTH", "YEAR" ], "description": "Period unit." } }, "required": [ "value", "unit" ], "additionalProperties": false }, "CardDefinitionPendingPointsInput": { "type": "object", "description": "Pending points activation policy.\nConditional requirements based on `type`:\n- `IMMEDIATE`: `period_based`, `fixed_dates` and `event_based` must be null/absent.\n- `PERIOD_BASED`: `period_based` is required; the other two must be null/absent.\n- `FIXED_DATES`: `fixed_dates` is required; the other two must be null/absent.\n- `EVENT_BASED`: `event_based` is required; the other two must be null/absent.", "properties": { "type": { "type": "string", "enum": [ "IMMEDIATE", "PERIOD_BASED", "FIXED_DATES", "EVENT_BASED" ], "description": "Pending points activation type. `IMMEDIATE` means no pending period." }, "period_based": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPendingPointsPeriodBasedInput" }, { "type": "null" } ], "description": "Period-based activation. Required when `type` is `PERIOD_BASED`, must be null otherwise." }, "fixed_dates": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPendingPointsFixedDatesInput" }, { "type": "null" } ], "description": "Fixed-dates activation. Required when `type` is `FIXED_DATES`, must be null otherwise." }, "event_based": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPendingPointsEventBasedInput" }, { "type": "null" } ], "description": "Event-based activation. Required when `type` is `EVENT_BASED`, must be null otherwise." } }, "required": [ "type" ], "additionalProperties": false }, "CardDefinitionPendingPointsPeriodBasedInput": { "type": "object", "description": "Period-based pending points activation - points activate after a fixed period.", "properties": { "period": { "$ref": "#/components/schemas/CardDefinitionPendingPointsPeriodBasedPeriodInput" } }, "required": [ "period" ], "additionalProperties": false }, "CardDefinitionPendingPointsPeriodBasedPeriodInput": { "type": "object", "description": "Pending period. The maximum `value` depends on `unit`:\n1-90 for `DAY`, 1-12 for `MONTH`, 1-1 for `YEAR` (enforced via if/then conditions).", "properties": { "unit": { "type": "string", "enum": [ "DAY", "MONTH", "YEAR" ], "description": "Period unit." }, "value": { "type": "integer", "minimum": 1, "maximum": 90, "description": "Period length. Maximum: 90 for `DAY`, 12 for `MONTH`, 1 for `YEAR`." } }, "required": [ "unit", "value" ], "additionalProperties": false }, "CardDefinitionPendingPointsFixedDatesInput": { "type": "object", "description": "Fixed-dates pending points activation - points activate on fixed calendar dates.", "properties": { "dates": { "type": "array", "items": { "$ref": "#/components/schemas/CardDefinitionPendingPointsFixedDatesDateInput" }, "minItems": 1, "maxItems": 20, "description": "List of calendar dates on which pending points activate (1-20 dates)." } }, "required": [ "dates" ], "additionalProperties": false }, "CardDefinitionPendingPointsFixedDatesDateInput": { "type": "object", "description": "A calendar date (day + month). The maximum `day` depends on `month`\n(enforced via if/then conditions): 29 for February, 30 for April/June/September/November,\n31 for the remaining months.", "properties": { "day": { "type": "integer", "minimum": 1, "maximum": 31, "description": "Day of the month. Maximum depends on the month: 29 for February, 30 for April, June, September, November, 31 otherwise." }, "month": { "type": "integer", "minimum": 1, "maximum": 12, "description": "Month number (1-12)." } }, "required": [ "day", "month" ], "additionalProperties": false }, "CardDefinitionPendingPointsEventBasedInput": { "type": "object", "description": "Event-based pending points activation - points activate when one of the configured custom events occurs, or are cancelled after the cancel period.", "properties": { "event_types": { "type": "array", "items": { "type": "string", "pattern": "^ms_[a-zA-Z0-9]+" }, "minItems": 1, "maxItems": 10, "description": "Custom event schema IDs (pattern `^ms_[a-zA-Z0-9]+`) that activate pending points. 1-10 unique items." }, "cancel_period": { "$ref": "#/components/schemas/CardDefinitionPendingPointsEventBasedCancelPeriodInput" } }, "required": [ "event_types", "cancel_period" ], "additionalProperties": false }, "CardDefinitionPendingPointsEventBasedCancelPeriodInput": { "type": "object", "description": "Period after which non-activated pending points are cancelled. The maximum `value`\ndepends on `unit`: 1-90 for `DAY`, 1-12 for `MONTH`, 1-1 for `YEAR`\n(enforced via if/then conditions).", "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 90, "description": "Period length. Maximum: 90 for `DAY`, 12 for `MONTH`, 1 for `YEAR`." }, "unit": { "type": "string", "enum": [ "DAY", "MONTH", "YEAR" ], "description": "Period unit." } }, "required": [ "value", "unit" ], "additionalProperties": false }, "CardDefinitionEarningLimitsInput": { "type": "object", "description": "Points earning limits.", "properties": { "global": { "$ref": "#/components/schemas/CardDefinitionEarningLimitsGlobalInput" }, "transactions": { "$ref": "#/components/schemas/CardDefinitionEarningLimitsTransactionsInput" } }, "required": [ "global", "transactions" ], "additionalProperties": false }, "CardDefinitionEarningLimitsGlobalInput": { "type": "object", "description": "Global (per card) earning limits. When `type` is `NO_LIMIT`, `limits` must be\nempty or null; when `type` is `LIMITED`, `limits` must contain exactly 1 limit.", "properties": { "type": { "type": "string", "enum": [ "NO_LIMIT", "LIMITED" ], "description": "Whether global earning limits apply." }, "limits": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/CardDefinitionEarningLimitsGlobalLimitInput" }, "maxItems": 1, "description": "Limit definitions. Empty/null when `type` is `NO_LIMIT`; exactly 1 item required when `type` is `LIMITED`." } }, "required": [ "type" ], "additionalProperties": false }, "CardDefinitionEarningLimitsGlobalLimitInput": { "description": "A global earning limit, discriminated by `type`:\n`BALANCE_BASED` (maximum card balance) or `TIME_BASED` (maximum points earned per period).", "oneOf": [ { "type": "object", "description": "Balance-based limit - the card balance cannot exceed `max` points.", "properties": { "type": { "type": "string", "const": "BALANCE_BASED", "description": "Limit type." }, "max": { "type": "integer", "minimum": 1, "description": "Maximum card balance in points." } }, "required": [ "type", "max" ], "additionalProperties": false }, { "type": "object", "description": "Time-based limit - at most `points.max` points can be earned per period.", "properties": { "type": { "type": "string", "const": "TIME_BASED", "description": "Limit type." }, "period": { "$ref": "#/components/schemas/CardDefinitionEarningLimitsGlobalTimeBasedPeriodInput" }, "points": { "$ref": "#/components/schemas/CardDefinitionEarningLimitsGlobalTimeBasedPointsInput" } }, "required": [ "type", "period", "points" ], "additionalProperties": false } ], "discriminator": { "propertyName": "type" } }, "CardDefinitionEarningLimitsGlobalTimeBasedPeriodInput": { "type": "object", "description": "Time-based earning limit period. When `type` is `CURRENT_PERIOD` (the only\nallowed value), `current_period` is required.", "properties": { "type": { "type": "string", "enum": [ "CURRENT_PERIOD" ], "description": "Period type. Currently only `CURRENT_PERIOD` (current calendar period) is supported." }, "current_period": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionEarningLimitsGlobalTimeBasedCurrentPeriodInput" }, { "type": "null" } ], "description": "Current-period configuration. Required when `type` is `CURRENT_PERIOD`." } }, "required": [ "type" ], "additionalProperties": false }, "CardDefinitionEarningLimitsGlobalTimeBasedCurrentPeriodInput": { "type": "object", "description": "Calendar period unit used to reset the time-based earning limit.", "properties": { "unit": { "type": "string", "enum": [ "DAY", "WEEK", "MONTH", "QUARTER", "YEAR" ], "description": "Calendar period unit." } }, "required": [ "unit" ], "additionalProperties": false }, "CardDefinitionEarningLimitsGlobalTimeBasedPointsInput": { "type": "object", "description": "Points cap for the time-based earning limit.", "properties": { "max": { "type": "integer", "minimum": 1, "maximum": 9007199254740991, "description": "Maximum points that can be earned within the period (1 to 9007199254740991)." } }, "required": [ "max" ], "additionalProperties": false }, "CardDefinitionEarningLimitsTransactionsInput": { "type": "object", "description": "Per-transaction earning limits. When `type` is `NO_LIMIT`, `limits` must be\nempty or null; when `type` is `LIMITED`, `limits` must contain at least 1 limit.\nEach limit `type` may appear at most once in the array.", "properties": { "type": { "type": "string", "enum": [ "NO_LIMIT", "LIMITED" ], "description": "Whether per-transaction earning limits apply." }, "limits": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/CardDefinitionEarningLimitsTransactionsLimitInput" }, "description": "Limit definitions with unique types. Empty/null when `type` is `NO_LIMIT`; at least 1 item required when `type` is `LIMITED`." } }, "required": [ "type" ], "additionalProperties": false }, "CardDefinitionEarningLimitsTransactionsLimitInput": { "description": "A per-transaction earning limit, discriminated by `type`:\n`POINTS` (maximum points earned per transaction) or `SPENDING`\n(minimum order amount required to earn points).", "oneOf": [ { "type": "object", "description": "Points limit - at most `max` points can be earned in a single transaction.", "properties": { "type": { "type": "string", "const": "POINTS", "description": "Limit type." }, "max": { "type": "integer", "minimum": 1, "description": "Maximum points earned per transaction." } }, "required": [ "type", "max" ], "additionalProperties": false }, { "type": "object", "description": "Spending threshold - points are only earned when the transaction amount is at least `min_amount`.", "properties": { "type": { "type": "string", "const": "SPENDING", "description": "Limit type." }, "min_amount": { "type": "integer", "minimum": 1, "description": "Minimum transaction amount required to earn points." } }, "required": [ "type", "min_amount" ], "additionalProperties": false } ], "discriminator": { "propertyName": "type" } }, "CardDefinitionSpendingLimitsInput": { "type": "object", "description": "Points spending limits.", "properties": { "global": { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsGlobalInput" }, "transactions": { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsTransactionsInput" } }, "required": [ "global", "transactions" ], "additionalProperties": false }, "CardDefinitionSpendingLimitsGlobalInput": { "type": "object", "description": "Global (per card) spending limits. When `type` is `NO_LIMIT`, `limits` must be\nempty or null; when `type` is `LIMITED`, `limits` must contain exactly 1 limit.", "properties": { "type": { "type": "string", "enum": [ "NO_LIMIT", "LIMITED" ], "description": "Whether global spending limits apply." }, "limits": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsGlobalLimitInput" }, "maxItems": 1, "description": "Limit definitions. Empty/null when `type` is `NO_LIMIT`; exactly 1 item required when `type` is `LIMITED`." } }, "required": [ "type" ], "additionalProperties": false }, "CardDefinitionSpendingLimitsGlobalLimitInput": { "description": "A global spending limit, discriminated by `type`:\n`SPENDING_BASED` (total points spent) or `TIME_BASED` (points spent per period).", "oneOf": [ { "type": "object", "description": "Spending-based limit - at most `max` points can be spent in total.", "properties": { "type": { "type": "string", "const": "SPENDING_BASED", "description": "Limit type." }, "max": { "type": "integer", "minimum": 1, "description": "Maximum total points spent." } }, "required": [ "type", "max" ], "additionalProperties": false }, { "type": "object", "description": "Time-based limit - at most `points.max` points can be spent per period.", "properties": { "type": { "type": "string", "const": "TIME_BASED", "description": "Limit type." }, "period": { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsGlobalTimeBasedPeriodInput" }, "points": { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsGlobalTimeBasedPointsInput" } }, "required": [ "type", "period", "points" ], "additionalProperties": false } ], "discriminator": { "propertyName": "type" } }, "CardDefinitionSpendingLimitsGlobalTimeBasedPeriodInput": { "type": "object", "description": "Time-based spending limit period. When `type` is `CURRENT_PERIOD` (the only\nallowed value), `current_period` is required.", "properties": { "type": { "type": "string", "enum": [ "CURRENT_PERIOD" ], "description": "Period type. Currently only `CURRENT_PERIOD` (current calendar period) is supported." }, "current_period": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsGlobalTimeBasedCurrentPeriodInput" }, { "type": "null" } ], "description": "Current-period configuration. Required when `type` is `CURRENT_PERIOD`." } }, "required": [ "type" ], "additionalProperties": false }, "CardDefinitionSpendingLimitsGlobalTimeBasedCurrentPeriodInput": { "type": "object", "description": "Calendar period unit used to reset the time-based spending limit.", "properties": { "unit": { "type": "string", "enum": [ "DAY", "WEEK", "MONTH", "QUARTER", "YEAR" ], "description": "Calendar period unit." } }, "required": [ "unit" ], "additionalProperties": false }, "CardDefinitionSpendingLimitsGlobalTimeBasedPointsInput": { "type": "object", "description": "Points cap for the time-based spending limit.", "properties": { "max": { "type": "integer", "minimum": 1, "maximum": 9007199254740991, "description": "Maximum points that can be spent within the period (1 to 9007199254740991)." } }, "required": [ "max" ], "additionalProperties": false }, "CardDefinitionSpendingLimitsTransactionsInput": { "type": "object", "description": "Per-transaction spending limits. When `type` is `NO_LIMIT`, `limits` must be\nempty or null; when `type` is `LIMITED`, `limits` must contain exactly 1 limit.", "properties": { "type": { "type": "string", "enum": [ "NO_LIMIT", "LIMITED" ], "description": "Whether per-transaction spending limits apply." }, "limits": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsTransactionsLimitInput" }, "maxItems": 1, "description": "Limit definitions. Empty/null when `type` is `NO_LIMIT`; exactly 1 item required when `type` is `LIMITED`." } }, "required": [ "type" ], "additionalProperties": false }, "CardDefinitionSpendingLimitsTransactionsLimitInput": { "description": "A per-transaction spending limit. Currently only the `POINTS` type is supported.", "oneOf": [ { "type": "object", "description": "Points limit - at most `max` points can be spent in a single transaction.", "properties": { "type": { "type": "string", "const": "POINTS", "description": "Limit type." }, "max": { "type": "integer", "minimum": 1, "description": "Maximum points spent per transaction." } }, "required": [ "type", "max" ], "additionalProperties": false } ], "discriminator": { "propertyName": "type" } }, "CardDefinitionRefundsInput": { "type": "object", "description": "Refund handling configuration.", "properties": { "spent_points": { "$ref": "#/components/schemas/CardDefinitionRefundsSpentPointsInput" }, "earned_points": { "$ref": "#/components/schemas/CardDefinitionRefundsEarnedPointsInput" } }, "required": [ "spent_points", "earned_points" ], "additionalProperties": false }, "CardDefinitionRefundsSpentPointsInput": { "type": "object", "description": "How points spent on a refunded order are handled. When `type` is `NONE`,\n`methods` must be empty or null; when `type` is `REFUNDABLE`, `methods`\nmust contain exactly 1 method.", "properties": { "type": { "type": "string", "enum": [ "NONE", "REFUNDABLE" ], "description": "Whether spent points are refundable." }, "methods": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/CardDefinitionRefundsSpentPointsMethodInput" }, "maxItems": 1, "description": "Refund methods. Empty/null when `type` is `NONE`; exactly 1 item required when `type` is `REFUNDABLE`. Currently only one method is allowed." } }, "required": [ "type" ], "additionalProperties": false }, "CardDefinitionRefundsSpentPointsMethodInput": { "description": "A spent points refund method. Currently only the `RETURN_POINTS` type is supported.", "oneOf": [ { "type": "object", "description": "Return spent points back to the card.", "properties": { "type": { "type": "string", "const": "RETURN_POINTS", "description": "Refund method type." }, "mode": { "type": "string", "enum": [ "REFUND_ALL", "REFUND_ITEM", "REFUND_AMOUNT" ], "description": "Refund mode: on full-order refund (`REFUND_ALL`), per-item refund (`REFUND_ITEM`) or amount-based refund (`REFUND_AMOUNT`)." } }, "required": [ "type", "mode" ], "additionalProperties": false } ], "discriminator": { "propertyName": "type" } }, "CardDefinitionRefundsEarnedPointsInput": { "type": "object", "description": "How points earned on a refunded order are handled. When `type` is `NONE`,\n`methods` must be empty or null; when `type` is `REFUNDABLE`, `methods`\nmust contain exactly 1 method.", "properties": { "type": { "type": "string", "enum": [ "NONE", "REFUNDABLE" ], "description": "Whether earned points are revocable on refund." }, "methods": { "type": [ "array", "null" ], "items": { "$ref": "#/components/schemas/CardDefinitionRefundsEarnedPointsMethodInput" }, "maxItems": 1, "description": "Revoke methods. Empty/null when `type` is `NONE`; exactly 1 item required when `type` is `REFUNDABLE`." } }, "required": [ "type" ], "additionalProperties": false }, "CardDefinitionRefundsEarnedPointsMethodInput": { "description": "An earned points revoke method, discriminated by `type`:\n`REVOKE_FROM_PENDING` (only valid when `pending_points.type` is `PERIOD_BASED`,\n`FIXED_DATES` or `EVENT_BASED`) or `REVOKE_FROM_BALANCE`.", "oneOf": [ { "type": "object", "description": "Revoke earned points from pending points.", "properties": { "type": { "type": "string", "const": "REVOKE_FROM_PENDING", "description": "Revoke method type." } }, "required": [ "type" ], "additionalProperties": false }, { "type": "object", "description": "Revoke earned points from the card balance.", "properties": { "type": { "type": "string", "const": "REVOKE_FROM_BALANCE", "description": "Revoke method type." }, "mode": { "type": "string", "enum": [ "REVOKE_TO_ZERO", "REVOKE_BELOW_ZERO" ], "description": "Revoke mode. `REVOKE_BELOW_ZERO` requires `balance_settings.allow_negative` to be `true`." } }, "required": [ "type", "mode" ], "additionalProperties": false } ], "discriminator": { "propertyName": "type" } }, "CardDefinitionBalanceSettingsInput": { "type": "object", "description": "Card balance settings. `allow_negative` can only be `true` when\n`points_expiration.type` is `NO_EXPIRATION`.", "properties": { "allow_negative": { "type": "boolean", "description": "Whether the card balance is allowed to go below zero." } }, "required": [ "allow_negative" ], "additionalProperties": false }, "CardDefinitionPayWithPointsInput": { "description": "Pay-with-points configuration, discriminated by `type`:\n`NO_PAYMENTS` (paying with points disabled) or `EXCHANGE_RATIO`\n(points can be exchanged for money using a formula).", "oneOf": [ { "type": "object", "description": "Paying with points is disabled.", "properties": { "type": { "type": "string", "const": "NO_PAYMENTS", "description": "Pay-with-points type." } }, "required": [ "type" ], "additionalProperties": false }, { "type": "object", "description": "Points can be exchanged for money at the configured ratio.", "properties": { "type": { "type": "string", "const": "EXCHANGE_RATIO", "description": "Pay-with-points type." }, "exchange_ratio": { "$ref": "#/components/schemas/CardDefinitionPayWithPointsExchangeRatioInput" } }, "required": [ "type", "exchange_ratio" ], "additionalProperties": false } ], "discriminator": { "propertyName": "type" } }, "CardDefinitionPayWithPointsExchangeRatioInput": { "type": "object", "description": "Exchange ratio used to convert points into money.", "properties": { "formula": { "oneOf": [ { "type": "string", "minLength": 1, "maxLength": 2000 }, { "type": "number" } ], "description": "Exchange ratio formula. A string expression (1-2000 characters) or a number.\nNumbers are converted to strings server-side." } }, "required": [ "formula" ], "additionalProperties": false }, "CardDefinitionListFilters": { "type": "object", "description": "Filters for the card definitions list endpoint. Each field accepts a\n`conditions` object; provided conditions must be valid for the field type.", "properties": { "junction": { "type": [ "string", "null" ], "enum": [ "AND", "OR", null ], "description": "Logical junction between field filters. Defaults to `AND`." }, "id": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionIdFilter" }, { "type": "null" } ], "description": "Filter by card definition ID." }, "name": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionStringFilter" }, { "type": "null" } ], "description": "Filter by card definition name." }, "type": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionTypeFilter" }, { "type": "null" } ], "description": "Filter by card definition type." }, "status": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionStatusFilter" }, { "type": "null" } ], "description": "Filter by card definition status (`ACTIVE` or `DRAFT` only)." }, "created_at": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionDateFilter" }, { "type": "null" } ], "description": "Filter by creation date." }, "updated_at": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionDateFilter" }, { "type": "null" } ], "description": "Filter by last update date." } }, "additionalProperties": false }, "CardDefinitionIdFilter": { "type": "object", "description": "ID field filter. Allowed conditions:\n`$is`, `$is_not`, `$in`, `$not_in`. Values must match the card definition ID pattern\n`^lcdef_[a-f0-9]+$`. `$is`/`$is_not` accept a single value (string or 1-element array);\n`$in`/`$not_in` accept 1-100 values.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "oneOf": [ { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 } ], "description": "ID equals the given value." }, "$is_not": { "oneOf": [ { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 } ], "description": "ID does not equal the given value." }, "$in": { "oneOf": [ { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 } ], "description": "ID is one of the given values (up to 100)." }, "$not_in": { "oneOf": [ { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 } ], "description": "ID is none of the given values (up to 100)." } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "CardDefinitionStringFilter": { "type": "object", "description": "String field filter. Allowed conditions: `$is`, `$is_not`, `$contains`, `$not_contain`,\n`$starts_with`, `$ends_with`, `$in`, `$not_in`, `$has_value`, `$is_unknown`.\nSingle-value conditions accept a string or a 1-element array; `$in`/`$not_in`\naccept 1-10 values; `$has_value`/`$is_unknown` are presence checks and ignore the value.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 } ], "description": "Value equals the given string." }, "$is_not": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 } ], "description": "Value does not equal the given string." }, "$contains": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 } ], "description": "Value contains the given substring." }, "$not_contain": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 } ], "description": "Value does not contain the given substring." }, "$starts_with": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 } ], "description": "Value starts with the given prefix." }, "$ends_with": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 } ], "description": "Value ends with the given suffix." }, "$in": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 10 } ], "description": "Value is one of the given strings (up to 10)." }, "$not_in": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 10 } ], "description": "Value is none of the given strings (up to 10)." }, "$has_value": { "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 } ], "description": "Field has a value (presence check; the provided value is ignored)." }, "$is_unknown": { "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 } ], "description": "Field has no value (presence check; the provided value is ignored)." } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "CardDefinitionTypeFilter": { "type": "object", "description": "Enum field filter for the card definition `type` field. Allowed conditions:\n`$is`, `$is_not`, `$in`, `$not_in`.\nValues must be one of: `INDIVIDUAL`.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "oneOf": [ { "type": "string", "enum": [ "INDIVIDUAL" ] }, { "type": "array", "items": { "type": "string", "enum": [ "INDIVIDUAL" ] }, "minItems": 1, "maxItems": 1 } ], "description": "Type equals the given value." }, "$is_not": { "oneOf": [ { "type": "string", "enum": [ "INDIVIDUAL" ] }, { "type": "array", "items": { "type": "string", "enum": [ "INDIVIDUAL" ] }, "minItems": 1, "maxItems": 1 } ], "description": "Type does not equal the given value." }, "$in": { "oneOf": [ { "type": "string", "enum": [ "INDIVIDUAL" ] }, { "type": "array", "items": { "type": "string", "enum": [ "INDIVIDUAL" ] }, "minItems": 1, "maxItems": 10 } ], "description": "Type is one of the given values (up to 10)." }, "$not_in": { "oneOf": [ { "type": "string", "enum": [ "INDIVIDUAL" ] }, { "type": "array", "items": { "type": "string", "enum": [ "INDIVIDUAL" ] }, "minItems": 1, "maxItems": 10 } ], "description": "Type is none of the given values (up to 10)." } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "CardDefinitionStatusFilter": { "type": "object", "description": "Enum field filter for the card definition `status` field. Allowed conditions:\n`$is`, `$is_not`, `$in`, `$not_in`.\nValues must be one of: `ACTIVE`, `DRAFT` (deleted card definitions are not listable).", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, { "type": "array", "items": { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, "minItems": 1, "maxItems": 1 } ], "description": "Status equals the given value." }, "$is_not": { "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, { "type": "array", "items": { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, "minItems": 1, "maxItems": 1 } ], "description": "Status does not equal the given value." }, "$in": { "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, { "type": "array", "items": { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, "minItems": 1, "maxItems": 10 } ], "description": "Status is one of the given values (up to 10)." }, "$not_in": { "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, { "type": "array", "items": { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, "minItems": 1, "maxItems": 10 } ], "description": "Status is none of the given values (up to 10)." } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "CardDefinitionDateFilter": { "type": "object", "description": "Date field filter. Allowed conditions:\n`$before`, `$after`, `$is`, `$more_than`, `$less_than`, `$has_value`, `$is_unknown`.\n`$before`/`$after` accept a date string; `$is`/`$more_than`/`$less_than` accept a\nnon-negative integer (number of days); `$has_value`/`$is_unknown` are presence checks.\nSingle values may be passed as a string or a 1-element array.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$before": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 } ], "description": "Date is before the given date (a date string)." }, "$after": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 } ], "description": "Date is after the given date (a date string)." }, "$is": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 } ], "description": "Date matches the given value expressed as a non-negative integer number of days." }, "$more_than": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 } ], "description": "Date is more than the given non-negative integer number of days ago." }, "$less_than": { "oneOf": [ { "type": "string" }, { "type": "array", "items": { "type": "string" }, "minItems": 1, "maxItems": 1 } ], "description": "Date is less than the given non-negative integer number of days ago." }, "$has_value": { "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 } ], "description": "Field has a value (presence check; the provided value is ignored)." }, "$is_unknown": { "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 } ], "description": "Field has no value (presence check; the provided value is ignored)." } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "CardDefinitionActivityListFilters": { "type": "object", "description": "Filters for the card definition activities list endpoint.", "properties": { "junction": { "type": [ "string", "null" ], "enum": [ "AND", "OR", null ], "description": "Logical junction between field filters. Defaults to `AND`." }, "id": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionActivityIdFilter" }, { "type": "null" } ], "description": "Filter by activity ID." }, "type": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionActivityTypeFilter" }, { "type": "null" } ], "description": "Filter by activity type." }, "created_at": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionDateFilter" }, { "type": "null" } ], "description": "Filter by activity creation date." } }, "additionalProperties": false }, "CardDefinitionActivityIdFilter": { "type": "object", "description": "ID field filter for activity IDs. Allowed conditions:\n`$is`, `$is_not`, `$in`, `$not_in`.\nValues must match the card definition activity ID pattern `^lacd_[a-f0-9]+$`.\n`$is`/`$is_not` accept a single value; `$in`/`$not_in` accept 1-100 values.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "oneOf": [ { "type": "string", "pattern": "^lacd_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lacd_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 } ], "description": "Activity ID equals the given value." }, "$is_not": { "oneOf": [ { "type": "string", "pattern": "^lacd_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lacd_[a-f0-9]+$" }, "minItems": 1, "maxItems": 1 } ], "description": "Activity ID does not equal the given value." }, "$in": { "oneOf": [ { "type": "string", "pattern": "^lacd_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lacd_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 } ], "description": "Activity ID is one of the given values (up to 100)." }, "$not_in": { "oneOf": [ { "type": "string", "pattern": "^lacd_[a-f0-9]+$" }, { "type": "array", "items": { "type": "string", "pattern": "^lacd_[a-f0-9]+$" }, "minItems": 1, "maxItems": 100 } ], "description": "Activity ID is none of the given values (up to 100)." } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "CardDefinitionActivityTypeFilter": { "type": "object", "description": "Enum field filter for activity types. Allowed conditions:\n`$is`, `$is_not`, `$in`, `$not_in`.\nValues must be one of: `vl.card_definition.created`, `vl.card_definition.updated`,\n`vl.card_definition.deleted`, `vl.card_definition.activated`,\n`vl.card_definition.deactivated`, `vl.card_definition.drafted`,\n`vl.card_definition.assigned`, `vl.card_definition.unassigned`.", "properties": { "conditions": { "type": "object", "minProperties": 1, "properties": { "$is": { "oneOf": [ { "type": "string", "enum": [ "vl.card_definition.created", "vl.card_definition.updated", "vl.card_definition.deleted", "vl.card_definition.activated", "vl.card_definition.deactivated", "vl.card_definition.drafted", "vl.card_definition.assigned", "vl.card_definition.unassigned" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.card_definition.created", "vl.card_definition.updated", "vl.card_definition.deleted", "vl.card_definition.activated", "vl.card_definition.deactivated", "vl.card_definition.drafted", "vl.card_definition.assigned", "vl.card_definition.unassigned" ] }, "minItems": 1, "maxItems": 1 } ], "description": "Activity type equals the given value." }, "$is_not": { "oneOf": [ { "type": "string", "enum": [ "vl.card_definition.created", "vl.card_definition.updated", "vl.card_definition.deleted", "vl.card_definition.activated", "vl.card_definition.deactivated", "vl.card_definition.drafted", "vl.card_definition.assigned", "vl.card_definition.unassigned" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.card_definition.created", "vl.card_definition.updated", "vl.card_definition.deleted", "vl.card_definition.activated", "vl.card_definition.deactivated", "vl.card_definition.drafted", "vl.card_definition.assigned", "vl.card_definition.unassigned" ] }, "minItems": 1, "maxItems": 1 } ], "description": "Activity type does not equal the given value." }, "$in": { "oneOf": [ { "type": "string", "enum": [ "vl.card_definition.created", "vl.card_definition.updated", "vl.card_definition.deleted", "vl.card_definition.activated", "vl.card_definition.deactivated", "vl.card_definition.drafted", "vl.card_definition.assigned", "vl.card_definition.unassigned" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.card_definition.created", "vl.card_definition.updated", "vl.card_definition.deleted", "vl.card_definition.activated", "vl.card_definition.deactivated", "vl.card_definition.drafted", "vl.card_definition.assigned", "vl.card_definition.unassigned" ] }, "minItems": 1, "maxItems": 10 } ], "description": "Activity type is one of the given values (up to 10)." }, "$not_in": { "oneOf": [ { "type": "string", "enum": [ "vl.card_definition.created", "vl.card_definition.updated", "vl.card_definition.deleted", "vl.card_definition.activated", "vl.card_definition.deactivated", "vl.card_definition.drafted", "vl.card_definition.assigned", "vl.card_definition.unassigned" ] }, { "type": "array", "items": { "type": "string", "enum": [ "vl.card_definition.created", "vl.card_definition.updated", "vl.card_definition.deleted", "vl.card_definition.activated", "vl.card_definition.deactivated", "vl.card_definition.drafted", "vl.card_definition.assigned", "vl.card_definition.unassigned" ] }, "minItems": 1, "maxItems": 10 } ], "description": "Activity type is none of the given values (up to 10)." } }, "additionalProperties": false } }, "required": [ "conditions" ], "additionalProperties": false }, "CardDefinition": { "type": "object", "description": "A card definition.", "properties": { "id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "Unique card definition ID." }, "name": { "type": "string", "description": "Card definition name." }, "type": { "type": "string", "enum": [ "INDIVIDUAL" ], "description": "Card definition type." }, "status": { "type": "string", "enum": [ "DRAFT", "ACTIVE", "DELETED" ], "description": "Current card definition status." }, "code_config": { "$ref": "#/components/schemas/CardDefinitionCodeConfig" }, "points_expiration": { "$ref": "#/components/schemas/CardDefinitionPointsExpiration" }, "pending_points": { "$ref": "#/components/schemas/CardDefinitionPendingPoints" }, "earning_limits": { "$ref": "#/components/schemas/CardDefinitionEarningLimits" }, "spending_limits": { "$ref": "#/components/schemas/CardDefinitionSpendingLimits" }, "refunds": { "$ref": "#/components/schemas/CardDefinitionRefunds" }, "balance_settings": { "$ref": "#/components/schemas/CardDefinitionBalanceSettings" }, "pay_with_points": { "$ref": "#/components/schemas/CardDefinitionPayWithPoints" }, "metadata": { "type": "object", "description": "Arbitrary key-value metadata. Empty object when not set." }, "created_at": { "type": "string", "format": "date-time", "description": "Creation timestamp (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last update timestamp (ISO 8601). Null when the card definition has never been updated." }, "object": { "type": "string", "const": "card_definition", "description": "Object type marker. Always `card_definition`." } }, "required": [ "id", "name", "type", "status", "code_config", "points_expiration", "pending_points", "earning_limits", "spending_limits", "refunds", "balance_settings", "pay_with_points", "metadata", "created_at", "updated_at", "object" ] }, "CardDefinitionCodeConfig": { "type": "object", "description": "Card code generation configuration. Always present with server-side defaults applied.", "properties": { "pattern": { "type": "string", "description": "Code pattern where each `#` is replaced with a random character from the charset." }, "length": { "type": "integer", "description": "Number of `#` placeholders in the pattern." }, "charset": { "type": "string", "description": "Characters used for code generation." }, "prefix": { "type": "string", "description": "Fixed prefix prepended to every generated code. Empty string when not set." }, "postfix": { "type": "string", "description": "Fixed postfix appended to every generated code. Empty string when not set." } }, "required": [ "pattern", "length", "charset", "prefix", "postfix" ] }, "CardDefinitionPointsExpiration": { "type": "object", "description": "Points expiration policy. Always present; defaults to `NO_EXPIRATION`.", "properties": { "type": { "type": "string", "enum": [ "NO_EXPIRATION", "ROLLING_EXPIRATION", "CALENDAR_EXPIRATION", "SLIDING_EXPIRATION" ], "description": "Points expiration type." }, "rolling_expiration": { "$ref": "#/components/schemas/CardDefinitionPointsExpirationRollingExpiration", "description": "Rolling expiration configuration. Only present when `type` is `ROLLING_EXPIRATION`." }, "calendar_expiration": { "$ref": "#/components/schemas/CardDefinitionPointsExpirationCalendarExpiration", "description": "Calendar expiration configuration. Only present when `type` is `CALENDAR_EXPIRATION`." }, "sliding_expiration": { "$ref": "#/components/schemas/CardDefinitionPointsExpirationSlidingExpiration", "description": "Sliding expiration configuration. Only present when `type` is `SLIDING_EXPIRATION`." } }, "required": [ "type" ] }, "CardDefinitionPointsExpirationRollingExpiration": { "type": "object", "description": "Rolling expiration configuration.", "properties": { "period": { "$ref": "#/components/schemas/CardDefinitionPeriod", "description": "Rolling expiration period. Unit is one of `DAY`, `MONTH`, `YEAR`." }, "rounding": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionPointsExpirationRollingExpirationRounding" }, { "type": "null" } ], "description": "Rounding applied to the calculated expiration date. Null when not configured." } }, "required": [ "period" ] }, "CardDefinitionPointsExpirationRollingExpirationRounding": { "type": "object", "description": "Rounding of the rolling expiration date.", "properties": { "type": { "type": "string", "enum": [ "END_OF_MONTH", "END_OF_QUARTER", "END_OF_HALF_YEAR", "END_OF_YEAR", "END_OF_PARTICULAR_MONTH" ], "description": "Rounding type." }, "value": { "type": "integer", "minimum": 1, "maximum": 12, "description": "Month number (1-12). Only present when `type` is `END_OF_PARTICULAR_MONTH`." } }, "required": [ "type" ] }, "CardDefinitionPointsExpirationCalendarExpiration": { "type": "object", "description": "Calendar expiration configuration.", "properties": { "expiration_dates": { "type": "array", "items": { "$ref": "#/components/schemas/CardDefinitionCalendarDate" }, "description": "Calendar dates on which points expire." } }, "required": [ "expiration_dates" ] }, "CardDefinitionPointsExpirationSlidingExpiration": { "type": "object", "description": "Sliding expiration configuration.", "properties": { "earning_activity": { "type": "boolean", "description": "Whether earning points resets the expiration window." }, "spending_activity": { "type": "boolean", "description": "Whether spending points resets the expiration window." }, "custom_activity": { "type": "boolean", "description": "Whether the configured custom events reset the expiration window." }, "custom_activity_types": { "type": "array", "items": { "type": "string" }, "description": "Custom event schema IDs that reset the expiration window. Empty array when `custom_activity` is false." }, "period": { "$ref": "#/components/schemas/CardDefinitionPeriod", "description": "Sliding expiration period. Unit is one of `DAY`, `MONTH`, `YEAR`." } }, "required": [ "custom_activity_types", "period" ] }, "CardDefinitionPeriod": { "type": "object", "description": "A period expressed as a value and unit.", "properties": { "value": { "type": "integer", "description": "Period length." }, "unit": { "type": "string", "enum": [ "DAY", "MONTH", "YEAR" ], "description": "Period unit." } }, "required": [ "value", "unit" ] }, "CardDefinitionCalendarDate": { "type": "object", "description": "A calendar date (day + month).", "properties": { "day": { "type": "integer", "minimum": 1, "maximum": 31, "description": "Day of the month." }, "month": { "type": "integer", "minimum": 1, "maximum": 12, "description": "Month number (1-12)." } }, "required": [ "day", "month" ] }, "CardDefinitionPendingPoints": { "type": "object", "description": "Pending points activation policy. Always present; defaults to `IMMEDIATE`.", "properties": { "type": { "type": "string", "enum": [ "IMMEDIATE", "PERIOD_BASED", "FIXED_DATES", "EVENT_BASED" ], "description": "Pending points activation type." }, "period_based": { "$ref": "#/components/schemas/CardDefinitionPendingPointsPeriodBased", "description": "Period-based activation. Only present when `type` is `PERIOD_BASED`." }, "fixed_dates": { "$ref": "#/components/schemas/CardDefinitionPendingPointsFixedDates", "description": "Fixed-dates activation. Only present when `type` is `FIXED_DATES`." }, "event_based": { "$ref": "#/components/schemas/CardDefinitionPendingPointsEventBased", "description": "Event-based activation. Only present when `type` is `EVENT_BASED`." } }, "required": [ "type" ] }, "CardDefinitionPendingPointsPeriodBased": { "type": "object", "description": "Period-based pending points activation.", "properties": { "period": { "$ref": "#/components/schemas/CardDefinitionPeriod", "description": "Pending period. Unit is one of `DAY`, `MONTH`, `YEAR`." } }, "required": [ "period" ] }, "CardDefinitionPendingPointsFixedDates": { "type": "object", "description": "Fixed-dates pending points activation.", "properties": { "dates": { "type": "array", "items": { "$ref": "#/components/schemas/CardDefinitionCalendarDate" }, "description": "Calendar dates on which pending points activate." } }, "required": [ "dates" ] }, "CardDefinitionPendingPointsEventBased": { "type": "object", "description": "Event-based pending points activation.", "properties": { "event_types": { "type": "array", "items": { "type": "string" }, "description": "Custom event schema IDs that activate pending points." }, "cancel_period": { "$ref": "#/components/schemas/CardDefinitionPeriod", "description": "Period after which non-activated pending points are cancelled. Unit is one of `DAY`, `MONTH`, `YEAR`." } }, "required": [ "event_types", "cancel_period" ] }, "CardDefinitionEarningLimits": { "type": "object", "description": "Points earning limits. Always present; defaults to `NO_LIMIT` for both scopes.", "properties": { "global": { "$ref": "#/components/schemas/CardDefinitionEarningLimitsGlobal" }, "transactions": { "$ref": "#/components/schemas/CardDefinitionEarningLimitsTransactions" } } }, "CardDefinitionEarningLimitsGlobal": { "type": "object", "description": "Global (per card) earning limits.", "properties": { "type": { "type": "string", "enum": [ "NO_LIMIT", "LIMITED" ], "description": "Whether global earning limits apply." }, "limits": { "type": "array", "items": { "$ref": "#/components/schemas/CardDefinitionEarningLimitsGlobalLimit" }, "description": "Limit definitions. Empty array when `type` is `NO_LIMIT`." } }, "required": [ "type", "limits" ] }, "CardDefinitionEarningLimitsGlobalLimit": { "description": "A global earning limit: `BALANCE_BASED` or `TIME_BASED`.", "oneOf": [ { "type": "object", "description": "Balance-based limit.", "properties": { "type": { "type": "string", "const": "BALANCE_BASED", "description": "Limit type." }, "max": { "type": "integer", "description": "Maximum card balance in points." } }, "required": [ "type", "max" ] }, { "type": "object", "description": "Time-based limit.", "properties": { "type": { "type": "string", "const": "TIME_BASED", "description": "Limit type." }, "period": { "$ref": "#/components/schemas/CardDefinitionLimitTimeBasedPeriod" }, "points": { "$ref": "#/components/schemas/CardDefinitionLimitTimeBasedPoints" } }, "required": [ "type" ] } ], "discriminator": { "propertyName": "type" } }, "CardDefinitionLimitTimeBasedPeriod": { "type": "object", "description": "Time-based limit period.", "properties": { "type": { "type": "string", "enum": [ "CURRENT_PERIOD" ], "description": "Period type." }, "current_period": { "type": "object", "description": "Current-period configuration. Present when `type` is `CURRENT_PERIOD`.", "properties": { "unit": { "type": "string", "enum": [ "DAY", "WEEK", "MONTH", "QUARTER", "YEAR" ], "description": "Calendar period unit." } }, "required": [ "unit" ] } }, "required": [ "type" ] }, "CardDefinitionLimitTimeBasedPoints": { "type": "object", "description": "Points cap for a time-based limit.", "properties": { "max": { "type": "integer", "description": "Maximum points within the period." } }, "required": [ "max" ] }, "CardDefinitionEarningLimitsTransactions": { "type": "object", "description": "Per-transaction earning limits.", "properties": { "type": { "type": "string", "enum": [ "NO_LIMIT", "LIMITED" ], "description": "Whether per-transaction earning limits apply." }, "limits": { "type": "array", "items": { "$ref": "#/components/schemas/CardDefinitionEarningLimitsTransactionsLimit" }, "description": "Limit definitions. Empty array when `type` is `NO_LIMIT`." } }, "required": [ "type", "limits" ] }, "CardDefinitionEarningLimitsTransactionsLimit": { "description": "A per-transaction earning limit: `POINTS` or `SPENDING`.", "oneOf": [ { "type": "object", "description": "Points limit.", "properties": { "type": { "type": "string", "const": "POINTS", "description": "Limit type." }, "max": { "type": "integer", "description": "Maximum points earned per transaction." } }, "required": [ "type", "max" ] }, { "type": "object", "description": "Spending threshold.", "properties": { "type": { "type": "string", "const": "SPENDING", "description": "Limit type." }, "min_amount": { "type": "integer", "description": "Minimum transaction amount required to earn points." } }, "required": [ "type", "min_amount" ] } ], "discriminator": { "propertyName": "type" } }, "CardDefinitionSpendingLimits": { "type": "object", "description": "Points spending limits. Always present; defaults to `NO_LIMIT` for both scopes.", "properties": { "global": { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsGlobal" }, "transactions": { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsTransactions" } } }, "CardDefinitionSpendingLimitsGlobal": { "type": "object", "description": "Global (per card) spending limits.", "properties": { "type": { "type": "string", "enum": [ "NO_LIMIT", "LIMITED" ], "description": "Whether global spending limits apply." }, "limits": { "type": "array", "items": { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsGlobalLimit" }, "description": "Limit definitions. Empty array when `type` is `NO_LIMIT`." } }, "required": [ "type", "limits" ] }, "CardDefinitionSpendingLimitsGlobalLimit": { "description": "A global spending limit: `SPENDING_BASED` or `TIME_BASED`.", "oneOf": [ { "type": "object", "description": "Spending-based limit.", "properties": { "type": { "type": "string", "const": "SPENDING_BASED", "description": "Limit type." }, "max": { "type": "integer", "description": "Maximum total points spent." } }, "required": [ "type", "max" ] }, { "type": "object", "description": "Time-based limit.", "properties": { "type": { "type": "string", "const": "TIME_BASED", "description": "Limit type." }, "period": { "$ref": "#/components/schemas/CardDefinitionLimitTimeBasedPeriod" }, "points": { "$ref": "#/components/schemas/CardDefinitionLimitTimeBasedPoints" } }, "required": [ "type" ] } ], "discriminator": { "propertyName": "type" } }, "CardDefinitionSpendingLimitsTransactions": { "type": "object", "description": "Per-transaction spending limits.", "properties": { "type": { "type": "string", "enum": [ "NO_LIMIT", "LIMITED" ], "description": "Whether per-transaction spending limits apply." }, "limits": { "type": "array", "items": { "$ref": "#/components/schemas/CardDefinitionSpendingLimitsTransactionsLimit" }, "description": "Limit definitions. Empty array when `type` is `NO_LIMIT`." } }, "required": [ "type", "limits" ] }, "CardDefinitionSpendingLimitsTransactionsLimit": { "type": "object", "description": "A per-transaction spending limit. Currently only the `POINTS` type exists.", "properties": { "type": { "type": "string", "const": "POINTS", "description": "Limit type." }, "max": { "type": "integer", "description": "Maximum points spent per transaction." } }, "required": [ "type", "max" ] }, "CardDefinitionRefunds": { "type": "object", "description": "Refund handling configuration. Always present; defaults to `NONE` for both scopes.", "properties": { "spent_points": { "$ref": "#/components/schemas/CardDefinitionRefundsSpentPoints" }, "earned_points": { "$ref": "#/components/schemas/CardDefinitionRefundsEarnedPoints" } }, "required": [ "spent_points", "earned_points" ] }, "CardDefinitionRefundsSpentPoints": { "type": "object", "description": "How points spent on a refunded order are handled.", "properties": { "type": { "type": "string", "enum": [ "NONE", "REFUNDABLE" ], "description": "Whether spent points are refundable." }, "methods": { "type": "array", "items": { "$ref": "#/components/schemas/CardDefinitionRefundsSpentPointsMethod" }, "description": "Refund methods. Empty array when `type` is `NONE`." } }, "required": [ "type", "methods" ] }, "CardDefinitionRefundsSpentPointsMethod": { "type": "object", "description": "A spent points refund method.", "properties": { "type": { "type": "string", "const": "RETURN_POINTS", "description": "Refund method type." }, "mode": { "type": "string", "enum": [ "REFUND_ALL", "REFUND_ITEM", "REFUND_AMOUNT" ], "description": "Refund mode." } }, "required": [ "type", "mode" ] }, "CardDefinitionRefundsEarnedPoints": { "type": "object", "description": "How points earned on a refunded order are handled.", "properties": { "type": { "type": "string", "enum": [ "NONE", "REFUNDABLE" ], "description": "Whether earned points are revocable on refund." }, "methods": { "type": "array", "items": { "$ref": "#/components/schemas/CardDefinitionRefundsEarnedPointsMethod" }, "description": "Revoke methods. Empty array when `type` is `NONE`." } }, "required": [ "type", "methods" ] }, "CardDefinitionRefundsEarnedPointsMethod": { "description": "An earned points revoke method: `REVOKE_FROM_PENDING` or `REVOKE_FROM_BALANCE`.", "oneOf": [ { "type": "object", "description": "Revoke earned points from pending points.", "properties": { "type": { "type": "string", "const": "REVOKE_FROM_PENDING", "description": "Revoke method type." } }, "required": [ "type" ] }, { "type": "object", "description": "Revoke earned points from the card balance.", "properties": { "type": { "type": "string", "const": "REVOKE_FROM_BALANCE", "description": "Revoke method type." }, "mode": { "type": "string", "enum": [ "REVOKE_TO_ZERO", "REVOKE_BELOW_ZERO" ], "description": "Revoke mode." } }, "required": [ "type", "mode" ] } ], "discriminator": { "propertyName": "type" } }, "CardDefinitionBalanceSettings": { "type": "object", "description": "Card balance settings. Always present; defaults to `allow_negative: false`.", "properties": { "allow_negative": { "type": "boolean", "description": "Whether the card balance is allowed to go below zero." } }, "required": [ "allow_negative" ] }, "CardDefinitionPayWithPoints": { "type": "object", "description": "Pay-with-points configuration. Always present; defaults to `NO_PAYMENTS`.", "properties": { "type": { "type": "string", "enum": [ "NO_PAYMENTS", "EXCHANGE_RATIO" ], "description": "Pay-with-points type." }, "exchange_ratio": { "type": "object", "description": "Exchange ratio. Only present when `type` is `EXCHANGE_RATIO`.", "properties": { "formula": { "type": "string", "description": "Exchange ratio formula (always returned as a string)." } }, "required": [ "formula" ] } }, "required": [ "type" ] }, "CardDefinitionListResponse": { "type": "object", "description": "Cursor-paginated list of card definitions.", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/CardDefinition" }, "description": "The card definitions in the current page." }, "cursor": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionListCursor" }, { "type": "null" } ], "description": "Pagination cursor. Null when there are no more results." }, "object": { "type": "string", "const": "list", "description": "Object type marker. Always `list`." } }, "required": [ "data", "cursor", "object" ] }, "CardDefinitionListCursor": { "type": "object", "description": "Pagination cursor.", "properties": { "next": { "type": "string", "pattern": "^lcrscdef_[a-f0-9]+$", "description": "Cursor ID to pass as the `cursor` query parameter to fetch the next page." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp after which the cursor expires." } }, "required": [ "next" ] }, "CardDefinitionActivity": { "type": "object", "description": "A card definition activity entry.", "properties": { "id": { "type": "string", "pattern": "^lacd_[a-f0-9]+$", "description": "Unique activity ID." }, "type": { "type": "string", "enum": [ "vl.card_definition.created", "vl.card_definition.updated", "vl.card_definition.deleted", "vl.card_definition.activated", "vl.card_definition.deactivated", "vl.card_definition.drafted", "vl.card_definition.assigned", "vl.card_definition.unassigned" ], "description": "Activity type." }, "data": { "type": "object", "description": "Activity payload. For created/updated/deleted/activated/deactivated/drafted\nactivities it contains a `card_definition` snapshot (the state of the card\ndefinition at the time of the activity). For assigned/unassigned activities\nit additionally contains `program` and `program_card_definition` snapshots.", "properties": { "card_definition": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinition" }, { "type": "null" } ], "description": "Snapshot of the card definition at the time of the activity." } } }, "created_at": { "type": "string", "format": "date-time", "description": "Activity timestamp (ISO 8601)." }, "group_id": { "type": "string", "description": "Groups related activities triggered by the same operation." }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "ID of the card definition this activity belongs to." }, "source": { "$ref": "#/components/schemas/CardDefinitionActivitySource", "description": "Source of the activity. Omitted when unknown." } }, "required": [ "id", "type", "data", "created_at", "card_definition_id" ] }, "CardDefinitionActivitySource": { "type": "object", "description": "Source that triggered the activity.", "properties": { "channel": { "type": "string", "enum": [ "USER_PORTAL", "API", "CLIENT_API", "INTERNAL" ], "description": "Channel through which the activity was triggered." }, "user": { "type": "object", "description": "User that triggered the activity. Omitted when not applicable.", "properties": { "id": { "type": "string", "description": "User ID." } } }, "api_key": { "type": "object", "description": "API key used to trigger the activity. Omitted when not applicable.", "properties": { "name": { "type": "string", "description": "API key name." }, "app_id": { "type": "string", "description": "Application ID of the API key." }, "client_app_id": { "type": "string", "description": "Client application ID of the API key." } } } } }, "CardDefinitionActivityListResponse": { "type": "object", "description": "Cursor-paginated list of card definition activities.", "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/CardDefinitionActivity" }, "description": "The activities in the current page." }, "cursor": { "oneOf": [ { "$ref": "#/components/schemas/CardDefinitionActivityListCursor" }, { "type": "null" } ], "description": "Pagination cursor. Null when there are no more results." }, "object": { "type": "string", "const": "list", "description": "Object type marker. Always `list`." } }, "required": [ "data", "cursor", "object" ] }, "CardDefinitionActivityListCursor": { "type": "object", "description": "Pagination cursor for the activities list.", "properties": { "next": { "type": "string", "pattern": "^lcrsacd_[a-f0-9]+$", "description": "Cursor ID to pass as the `cursor` query parameter to fetch the next page." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp after which the cursor expires." } }, "required": [ "next" ] }, "EarningRuleMetadata": { "type": "object", "description": "Arbitrary key-value metadata; any JSON object is accepted.", "additionalProperties": true }, "EarningRuleCreateRequest": { "type": "object", "description": "Request body for creating an earning rule.", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Earning rule name." }, "trigger": { "$ref": "#/components/schemas/EarningRuleTrigger" }, "earnings": { "type": "array", "minItems": 1, "description": "Earning definitions (rules and effects) evaluated when the trigger fires.", "items": { "$ref": "#/components/schemas/EarningRuleEarningCreate" } }, "status": { "type": "string", "enum": [ "DRAFT", "ACTIVE" ], "description": "Initial status. Only `DRAFT` and `ACTIVE` are allowed at creation. Defaults to `DRAFT`." }, "error": { "description": "Default error returned when rule validation fails. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleError" }, { "type": "null" } ] }, "validity_hours": { "description": "Hours during which the rule is active. Defaults to `{ \"type\": \"ANY_TIME\" }` when omitted. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleValidityHours" }, { "type": "null" } ] }, "start_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date-time from which the rule is active. Nullable." }, "end_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date-time until which the rule is active. Nullable." }, "metadata": { "description": "Arbitrary key-value metadata. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleMetadata" }, { "type": "null" } ] }, "trigger_limits": { "description": "Cooldown and frequency limits for the trigger. Defaults to `{ \"cooldown\": { \"type\": \"NO_COOLDOWN\" }, \"frequency\": { \"type\": \"NO_LIMIT\" } }` when omitted. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleTriggerLimits" }, { "type": "null" } ] } }, "required": [ "name", "trigger", "earnings" ], "additionalProperties": false }, "EarningRuleUpdateRequest": { "type": "object", "description": "Request body for updating an earning rule. All properties are optional; `status` is not updatable here.", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Earning rule name." }, "trigger": { "$ref": "#/components/schemas/EarningRuleTrigger" }, "earnings": { "type": "array", "minItems": 1, "description": "Earning definitions. Items with an `id` update existing earning items; items without an `id` are created. Omitted existing items are removed.", "items": { "$ref": "#/components/schemas/EarningRuleEarningUpdate" } }, "error": { "description": "Default error returned when rule validation fails. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleError" }, { "type": "null" } ] }, "validity_hours": { "description": "Hours during which the rule is active. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleValidityHours" }, { "type": "null" } ] }, "start_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date-time from which the rule is active. Nullable." }, "end_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date-time until which the rule is active. Nullable." }, "metadata": { "description": "Arbitrary key-value metadata. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleMetadata" }, { "type": "null" } ] }, "trigger_limits": { "description": "Cooldown and frequency limits for the trigger. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleTriggerLimits" }, { "type": "null" } ] } }, "additionalProperties": false }, "EarningRuleTrigger": { "type": "object", "description": "Event that triggers the earning rule. Depending on `event`, either `custom_event` or `segment` is required and the other trigger contexts must be null/absent.", "properties": { "event": { "type": "string", "enum": [ "customer.order.paid", "customer.custom_event", "customer.segment.entered" ], "description": "Triggering event type." }, "custom_event": { "description": "Custom event trigger context. Required when `event` is `customer.custom_event`; must be null for other events.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleTriggerCustomEvent" }, { "type": "null" } ] }, "segment": { "description": "Segment trigger context. Required when `event` is `customer.segment.entered`; must be null for other events.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleTriggerSegment" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "event" ] }, { "if": { "properties": { "event": { "const": "customer.order.paid" } } }, "then": { "properties": { "custom_event": { "type": "null" }, "segment": { "type": "null" } } } }, { "if": { "properties": { "event": { "const": "customer.custom_event" } } }, "then": { "required": [ "custom_event" ], "properties": { "custom_event": { "$ref": "#/components/schemas/EarningRuleTriggerCustomEvent" }, "segment": { "type": "null" } } } }, { "if": { "properties": { "event": { "const": "customer.segment.entered" } } }, "then": { "required": [ "segment" ], "properties": { "custom_event": { "type": "null" }, "segment": { "$ref": "#/components/schemas/EarningRuleTriggerSegment" } } } } ] }, "EarningRuleTriggerCustomEvent": { "type": "object", "description": "Custom event trigger configuration.", "properties": { "schema_id": { "type": "string", "pattern": "^ms_[a-zA-Z0-9]+", "description": "Custom event schema ID (`ms_...`)." } }, "required": [ "schema_id" ], "additionalProperties": false }, "EarningRuleTriggerSegment": { "type": "object", "description": "Segment trigger configuration.", "properties": { "id": { "type": "string", "pattern": "^seg_[a-zA-Z0-9]+", "description": "Segment ID (`seg_...`)." } }, "required": [ "id" ], "additionalProperties": false }, "EarningRuleEarningCreate": { "type": "object", "description": "A single earning definition combining optional validation rules with effects.", "properties": { "rules": { "description": "Validation rules group evaluated before applying effects. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleRulesGroup" }, { "type": "null" } ] }, "effects": { "type": "array", "minItems": 1, "description": "Effects applied when the rules match.", "items": { "$ref": "#/components/schemas/EarningRuleEffect" } }, "name": { "type": [ "string", "null" ], "maxLength": 200, "description": "Optional earning item name. Nullable." }, "tier_rules": { "description": "Tier requirements restricting which members can earn. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleTierRules" }, { "type": "null" } ] } }, "required": [ "effects" ], "additionalProperties": false }, "EarningRuleEarningUpdate": { "type": "object", "description": "A single earning definition for updates. Same as the create variant plus an optional `id` referencing an existing earning item.", "properties": { "id": { "type": "string", "pattern": "^lernei_[a-f0-9]+$", "description": "Existing earning item ID (`lernei_...`). Omit to create a new item." }, "rules": { "description": "Validation rules group evaluated before applying effects. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleRulesGroup" }, { "type": "null" } ] }, "effects": { "type": "array", "minItems": 1, "description": "Effects applied when the rules match.", "items": { "$ref": "#/components/schemas/EarningRuleEffect" } }, "name": { "type": [ "string", "null" ], "maxLength": 200, "description": "Optional earning item name. Nullable." }, "tier_rules": { "description": "Tier requirements restricting which members can earn. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleTierRules" }, { "type": "null" } ] } }, "required": [ "effects" ], "additionalProperties": false }, "EarningRuleRulesGroup": { "type": "object", "description": "Group of rule definitions combined by a logical formula. Besides `logic`, only positive-integer keys are allowed (property names must match `^[1-9]\\d*$`), each referencing a rule definition. The `logic` value is a logical expression referencing the numbered rules, e.g. `\"1 and 2\"` or `\"1 and (2 or 3)\"`. At least one numbered rule is required (`minProperties: 2` including `logic`).", "properties": { "logic": { "type": "string", "description": "Logical expression combining the numbered rule definitions, e.g. `\"1 and 2\"`." } }, "patternProperties": { "^[1-9]\\d*$": { "$ref": "#/components/schemas/EarningRuleDefinition" } }, "required": [ "logic" ], "minProperties": 2, "additionalProperties": false }, "EarningRuleDefinition": { "type": "object", "description": "A single validation rule definition.", "properties": { "name": { "type": "string", "enum": [ "customer.segment", "customer.metadata", "order.amount", "order.initial_amount", "order.total_amount", "order.metadata", "order.items.count", "order.items.price_any", "order.items.price_each", "order.items.every", "order.items.any", "order.items.none", "order.items.quantity", "order.items.aggregated_quantity", "order.items.price", "order.items.aggregated_amount", "order.items.cheapest", "order.items.most_expensive", "order.items.metadata", "custom_event.metadata" ], "description": "Rule definition name. Which names are allowed depends on the trigger event: `customer.order.paid` allows customer.* plus all order.* names; `customer.custom_event` allows customer.* plus custom_event.metadata; `customer.segment.entered` allows only customer.* names." }, "property": { "type": [ "string", "null" ], "description": "Metadata property name the rule applies to (for metadata-based rules). Nullable." }, "schema_id": { "type": [ "string", "null" ], "description": "Custom event schema ID for custom_event.metadata rules. Nullable." }, "error": { "description": "Error returned when this specific rule fails. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleError" }, { "type": "null" } ] }, "rules": { "description": "Nested rule group (recursive). Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleRulesGroup" }, { "type": "null" } ] }, "conditions": { "$ref": "#/components/schemas/EarningRuleConditions" } }, "additionalProperties": false }, "EarningRuleConditions": { "type": "object", "description": "Conditions keyed by operator. Allowed operators: `$is`, `$is_not`, `$in`, `$not_in`, `$less_than`, `$less_than_or_equal`, `$more_than`, `$more_than_or_equal`, `$from` (each an array of values), and `$dow` (an array of day-of-week integers 0-6). At most 10 operator properties are allowed (`maxProperties: 10`).", "properties": { "$dow": { "type": "array", "minItems": 1, "maxItems": 7, "description": "Day-of-week condition (0 = Sunday ... 6 = Saturday).", "items": { "type": "integer", "minimum": 0, "maximum": 6 } } }, "patternProperties": { "^(\\$is|\\$is_not|\\$in|\\$not_in|\\$less_than|\\$less_than_or_equal|\\$more_than|\\$more_than_or_equal|\\$from)$": { "type": "array", "minItems": 1, "description": "Condition values - strings, integers, booleans or object references.", "items": { "oneOf": [ { "$ref": "#/components/schemas/EarningRuleConditionObject" }, { "type": "string" }, { "type": "integer" }, { "type": "boolean" } ] } } }, "maxProperties": 10, "additionalProperties": false }, "EarningRuleConditionObject": { "type": "object", "description": "Object reference used as a condition value (e.g. product, SKU or segment reference).", "properties": { "id": { "type": "string", "description": "Referenced object ID." }, "object": { "type": "string", "description": "Referenced object type name." }, "source_id": { "type": [ "string", "null" ], "description": "Source ID of the referenced object. Nullable." }, "type": { "type": [ "string", "null" ], "description": "Additional object subtype. Nullable." } }, "additionalProperties": false }, "EarningRuleError": { "type": "object", "description": "Custom error message configuration.", "properties": { "message": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Error message shown when validation fails." } }, "required": [ "message" ], "additionalProperties": false }, "EarningRuleEffect": { "type": "object", "description": "Effect applied when an earning is triggered. Depending on `type`, exactly one of `points`, `points_proportional` or `benefit` is required and the others must be null/absent.", "properties": { "type": { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "BENEFIT" ], "description": "Effect type." }, "points": { "$ref": "#/components/schemas/EarningRuleEffectPoints" }, "points_proportional": { "$ref": "#/components/schemas/EarningRuleEffectPointsProportional" }, "benefit": { "$ref": "#/components/schemas/EarningRuleEffectBenefit" } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "POINTS" } } }, "then": { "required": [ "points" ], "properties": { "points": { "$ref": "#/components/schemas/EarningRuleEffectPoints" }, "points_proportional": { "type": "null" }, "benefit": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "POINTS_PROPORTIONAL" } } }, "then": { "required": [ "points_proportional" ], "properties": { "points": { "type": "null" }, "points_proportional": { "$ref": "#/components/schemas/EarningRuleEffectPointsProportional" }, "benefit": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "BENEFIT" } } }, "then": { "required": [ "benefit" ], "properties": { "points": { "type": "null" }, "points_proportional": { "type": "null" }, "benefit": { "$ref": "#/components/schemas/EarningRuleEffectBenefit" } } } } ] }, "EarningRuleEffectPoints": { "type": "object", "description": "Fixed points effect - awards a fixed number of points to a card definition.", "properties": { "value": { "type": "integer", "minimum": 0, "maximum": 9007199254740991, "description": "Fixed number of points to award." }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "Card definition ID (`lcdef_...`) the points are awarded to." }, "points_expiration": { "description": "Optional expiration override for the awarded points. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleEffectPointsExpiration" }, { "type": "null" } ] } }, "required": [ "value", "card_definition_id" ], "additionalProperties": false }, "EarningRuleEffectPointsProportional": { "type": "object", "description": "Proportional points effect - awards points using an \"every X gives Y points\" formula.\nDepending on `calculation_type`, one specific configuration object is required and the\nothers must be null/absent:\n- `PRE_DISCOUNT_ORDER_AMOUNT`: requires `order.amount`\n- `POST_DISCOUNT_ORDER_AMOUNT`: requires `order.total_amount`\n- `ORDER_METADATA_VALUE`: requires `order.metadata`\n- `CUSTOMER_METADATA_VALUE`: requires `customer.metadata`\n- `CUSTOM_EVENT_METADATA_VALUE`: requires `custom_event.metadata`\n- `PRE_DISCOUNT_ORDER_ITEMS_AMOUNT`: requires `order_items.amount`\n- `POST_DISCOUNT_ORDER_ITEMS_AMOUNT`: requires `order_items.subtotal_amount`\n- `ORDER_ITEMS_QUANTITY`: requires `order_items.quantity`\nThe trigger further restricts allowed calculation types:\n`customer.order.paid` allows all order/order-items types plus `CUSTOMER_METADATA_VALUE`;\n`customer.custom_event` allows `CUSTOMER_METADATA_VALUE` and `CUSTOM_EVENT_METADATA_VALUE`;\n`customer.segment.entered` allows only `CUSTOMER_METADATA_VALUE`.", "properties": { "calculation_type": { "type": "string", "enum": [ "PRE_DISCOUNT_ORDER_AMOUNT", "POST_DISCOUNT_ORDER_AMOUNT", "PRE_DISCOUNT_ORDER_ITEMS_AMOUNT", "POST_DISCOUNT_ORDER_ITEMS_AMOUNT", "ORDER_ITEMS_QUANTITY", "ORDER_METADATA_VALUE", "CUSTOMER_METADATA_VALUE", "CUSTOM_EVENT_METADATA_VALUE" ], "description": "How the proportional points are calculated." }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "Card definition ID (`lcdef_...`) the points are awarded to." }, "points_expiration": { "description": "Optional expiration override for the awarded points. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleEffectPointsExpiration" }, { "type": "null" } ] }, "order": { "$ref": "#/components/schemas/EarningRulePointsProportionalOrder" }, "customer": { "$ref": "#/components/schemas/EarningRulePointsProportionalCustomer" }, "custom_event": { "$ref": "#/components/schemas/EarningRulePointsProportionalCustomEvent" }, "order_items": { "$ref": "#/components/schemas/EarningRulePointsProportionalOrderItems" } }, "required": [ "calculation_type", "card_definition_id" ], "additionalProperties": false, "allOf": [ { "if": { "properties": { "calculation_type": { "const": "PRE_DISCOUNT_ORDER_AMOUNT" } } }, "then": { "required": [ "order" ], "properties": { "order": { "type": "object", "required": [ "amount" ] }, "customer": { "type": "null" }, "custom_event": { "type": "null" }, "order_items": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "POST_DISCOUNT_ORDER_AMOUNT" } } }, "then": { "required": [ "order" ], "properties": { "order": { "type": "object", "required": [ "total_amount" ] }, "customer": { "type": "null" }, "custom_event": { "type": "null" }, "order_items": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "ORDER_METADATA_VALUE" } } }, "then": { "required": [ "order" ], "properties": { "order": { "type": "object", "required": [ "metadata" ] }, "customer": { "type": "null" }, "custom_event": { "type": "null" }, "order_items": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "CUSTOMER_METADATA_VALUE" } } }, "then": { "required": [ "customer" ], "properties": { "customer": { "$ref": "#/components/schemas/EarningRulePointsProportionalCustomer" }, "order": { "type": "null" }, "custom_event": { "type": "null" }, "order_items": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "CUSTOM_EVENT_METADATA_VALUE" } } }, "then": { "required": [ "custom_event" ], "properties": { "custom_event": { "$ref": "#/components/schemas/EarningRulePointsProportionalCustomEvent" }, "order": { "type": "null" }, "customer": { "type": "null" }, "order_items": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "PRE_DISCOUNT_ORDER_ITEMS_AMOUNT" } } }, "then": { "required": [ "order_items" ], "properties": { "order_items": { "type": "object", "required": [ "amount" ] }, "order": { "type": "null" }, "customer": { "type": "null" }, "custom_event": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "POST_DISCOUNT_ORDER_ITEMS_AMOUNT" } } }, "then": { "required": [ "order_items" ], "properties": { "order_items": { "type": "object", "required": [ "subtotal_amount" ] }, "order": { "type": "null" }, "customer": { "type": "null" }, "custom_event": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "ORDER_ITEMS_QUANTITY" } } }, "then": { "required": [ "order_items" ], "properties": { "order_items": { "type": "object", "required": [ "quantity" ] }, "order": { "type": "null" }, "customer": { "type": "null" }, "custom_event": { "type": "null" } } } } ] }, "EarningRuleEffectBenefit": { "type": "object", "description": "Benefit effect - grants a predefined benefit.", "properties": { "id": { "type": "string", "pattern": "^lben_[a-f0-9]+$", "description": "Benefit ID (`lben_...`)." } }, "required": [ "id" ], "additionalProperties": false }, "EarningRulePointsProportionalEvery": { "type": "object", "description": "\"Every X gives Y points\" formula based on an amount.", "properties": { "every": { "type": "integer", "minimum": 1, "maximum": 9007199254740991, "description": "The divisor - every this amount (e.g. in cents) awards `value` points." }, "value": { "type": "number", "minimum": 0, "maximum": 9007199254740991, "description": "Points awarded per `every` unit." } }, "required": [ "every", "value" ], "additionalProperties": false }, "EarningRulePointsProportionalMetadata": { "type": "object", "description": "\"Every X gives Y points\" formula based on a numeric metadata property.", "properties": { "every": { "type": "integer", "minimum": 1, "maximum": 9007199254740991, "description": "The divisor - every this metadata value awards `value` points." }, "value": { "type": "number", "minimum": 0, "maximum": 9007199254740991, "description": "Points awarded per `every` unit." }, "property": { "type": "string", "minLength": 1, "description": "Metadata property name holding the numeric value." } }, "required": [ "every", "value", "property" ], "additionalProperties": false }, "EarningRulePointsProportionalApplicableTo": { "type": "object", "description": "Criterion selecting order items the calculation applies to. Depending on `type`, exactly one of `product`, `sku` or `products_collection` is required and the others must be null/absent.", "properties": { "type": { "type": "string", "enum": [ "product", "sku", "products_collection" ], "description": "Type of the referenced object." }, "product": { "$ref": "#/components/schemas/EarningRulePointsProportionalApplicableToProduct" }, "sku": { "$ref": "#/components/schemas/EarningRulePointsProportionalApplicableToSku" }, "products_collection": { "$ref": "#/components/schemas/EarningRulePointsProportionalApplicableToProductsCollection" } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "product" } } }, "then": { "required": [ "product" ], "properties": { "product": { "$ref": "#/components/schemas/EarningRulePointsProportionalApplicableToProduct" }, "sku": { "type": "null" }, "products_collection": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "sku" } } }, "then": { "required": [ "sku" ], "properties": { "sku": { "$ref": "#/components/schemas/EarningRulePointsProportionalApplicableToSku" }, "product": { "type": "null" }, "products_collection": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "products_collection" } } }, "then": { "required": [ "products_collection" ], "properties": { "products_collection": { "$ref": "#/components/schemas/EarningRulePointsProportionalApplicableToProductsCollection" }, "product": { "type": "null" }, "sku": { "type": "null" } } } } ] }, "EarningRulePointsProportionalApplicableToProduct": { "type": "object", "description": "Product reference.", "properties": { "id": { "type": "string", "pattern": "^prod_[a-f0-9]+", "description": "Product ID (`prod_...`)." } }, "required": [ "id" ], "additionalProperties": false }, "EarningRulePointsProportionalApplicableToSku": { "type": "object", "description": "SKU reference.", "properties": { "id": { "type": "string", "pattern": "^sku_[a-f0-9]+", "description": "SKU ID (`sku_...`)." } }, "required": [ "id" ], "additionalProperties": false }, "EarningRulePointsProportionalApplicableToProductsCollection": { "type": "object", "description": "Products collection reference.", "properties": { "id": { "type": "string", "pattern": "^pc_[a-zA-Z0-9]+", "description": "Products collection ID (`pc_...`)." } }, "required": [ "id" ], "additionalProperties": false }, "EarningRulePointsProportionalOrderItemsCalculation": { "type": "object", "description": "Order items based calculation - \"every X gives Y points\" applied to items matching the `applicable_to` criteria.", "properties": { "every": { "type": "integer", "minimum": 1, "maximum": 9007199254740991, "description": "The divisor - every this amount/quantity awards `value` points." }, "value": { "type": "number", "minimum": 0, "maximum": 9007199254740991, "description": "Points awarded per `every` unit." }, "applicable_to": { "type": "array", "minItems": 1, "description": "Product/SKU/collection criteria selecting matching order items.", "items": { "$ref": "#/components/schemas/EarningRulePointsProportionalApplicableTo" } } }, "required": [ "every", "value", "applicable_to" ], "additionalProperties": false }, "EarningRulePointsProportionalOrder": { "type": "object", "description": "Order-based proportional calculation configuration. `amount` is used by `PRE_DISCOUNT_ORDER_AMOUNT`, `total_amount` by `POST_DISCOUNT_ORDER_AMOUNT` and `metadata` by `ORDER_METADATA_VALUE`.", "properties": { "amount": { "$ref": "#/components/schemas/EarningRulePointsProportionalEvery" }, "total_amount": { "$ref": "#/components/schemas/EarningRulePointsProportionalEvery" }, "metadata": { "$ref": "#/components/schemas/EarningRulePointsProportionalMetadata" } }, "additionalProperties": false }, "EarningRulePointsProportionalCustomer": { "type": "object", "description": "Customer-based proportional calculation configuration (`CUSTOMER_METADATA_VALUE`).", "properties": { "metadata": { "$ref": "#/components/schemas/EarningRulePointsProportionalMetadata" } }, "required": [ "metadata" ], "additionalProperties": false }, "EarningRulePointsProportionalCustomEvent": { "type": "object", "description": "Custom event based proportional calculation configuration (`CUSTOM_EVENT_METADATA_VALUE`).", "properties": { "metadata": { "$ref": "#/components/schemas/EarningRulePointsProportionalMetadata" } }, "required": [ "metadata" ], "additionalProperties": false }, "EarningRulePointsProportionalOrderItems": { "type": "object", "description": "Order items based proportional calculation configuration. `amount` is used by `PRE_DISCOUNT_ORDER_ITEMS_AMOUNT`, `subtotal_amount` by `POST_DISCOUNT_ORDER_ITEMS_AMOUNT` and `quantity` by `ORDER_ITEMS_QUANTITY`.", "properties": { "amount": { "$ref": "#/components/schemas/EarningRulePointsProportionalOrderItemsCalculation" }, "subtotal_amount": { "$ref": "#/components/schemas/EarningRulePointsProportionalOrderItemsCalculation" }, "quantity": { "$ref": "#/components/schemas/EarningRulePointsProportionalOrderItemsCalculation" } }, "additionalProperties": false }, "EarningRuleEffectPointsExpiration": { "type": "object", "description": "Points expiration override. Depending on `type`, exactly one of `rolling_expiration`, `calendar_expiration` or `sliding_expiration` is required; for `NO_EXPIRATION` all three must be null/absent.", "properties": { "type": { "type": "string", "enum": [ "NO_EXPIRATION", "ROLLING_EXPIRATION", "CALENDAR_EXPIRATION", "SLIDING_EXPIRATION" ], "description": "Points expiration type." }, "rolling_expiration": { "description": "Rolling expiration configuration. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleEffectPointsExpirationRollingExpiration" }, { "type": "null" } ] }, "calendar_expiration": { "description": "Calendar expiration configuration. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleEffectPointsExpirationCalendarExpiration" }, { "type": "null" } ] }, "sliding_expiration": { "description": "Sliding expiration configuration. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleEffectPointsExpirationSlidingExpiration" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "NO_EXPIRATION" } } }, "then": { "properties": { "rolling_expiration": { "type": "null" }, "calendar_expiration": { "type": "null" }, "sliding_expiration": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "ROLLING_EXPIRATION" } } }, "then": { "required": [ "rolling_expiration" ], "properties": { "rolling_expiration": { "$ref": "#/components/schemas/EarningRuleEffectPointsExpirationRollingExpiration" }, "calendar_expiration": { "type": "null" }, "sliding_expiration": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "CALENDAR_EXPIRATION" } } }, "then": { "required": [ "calendar_expiration" ], "properties": { "rolling_expiration": { "type": "null" }, "calendar_expiration": { "$ref": "#/components/schemas/EarningRuleEffectPointsExpirationCalendarExpiration" }, "sliding_expiration": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "SLIDING_EXPIRATION" } } }, "then": { "required": [ "sliding_expiration" ], "properties": { "rolling_expiration": { "type": "null" }, "calendar_expiration": { "type": "null" }, "sliding_expiration": { "$ref": "#/components/schemas/EarningRuleEffectPointsExpirationSlidingExpiration" } } } } ] }, "EarningRuleEffectPointsExpirationRollingExpiration": { "type": "object", "description": "Rolling expiration - points expire a fixed period after earning.", "properties": { "period": { "$ref": "#/components/schemas/EarningRuleEffectPointsExpirationRollingExpirationPeriod" }, "rounding": { "description": "Optional rounding of the calculated expiration date. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleEffectPointsExpirationRollingExpirationRounding" }, { "type": "null" } ] } }, "required": [ "period" ], "additionalProperties": false }, "EarningRuleEffectPointsExpirationRollingExpirationPeriod": { "type": "object", "description": "Rolling expiration period. The maximum `value` depends on `unit`: `DAY` - 90, `MONTH` - 12, `YEAR` - 5.", "properties": { "unit": { "type": "string", "enum": [ "DAY", "MONTH", "YEAR" ], "description": "Period unit." }, "value": { "type": "integer", "minimum": 1, "description": "Period length. Maximum depends on `unit`: 90 for DAY, 12 for MONTH, 5 for YEAR." } }, "additionalProperties": false, "allOf": [ { "required": [ "unit", "value" ] }, { "if": { "properties": { "unit": { "const": "DAY" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 90 } } } }, { "if": { "properties": { "unit": { "const": "MONTH" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 12 } } } }, { "if": { "properties": { "unit": { "const": "YEAR" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 5 } } } } ] }, "EarningRuleEffectPointsExpirationRollingExpirationRounding": { "type": "object", "description": "Rounding of the rolling expiration date. `value` (the month number, 1-12) is required for `END_OF_PARTICULAR_MONTH` and must be null for all other rounding types.", "properties": { "type": { "type": "string", "enum": [ "END_OF_MONTH", "END_OF_QUARTER", "END_OF_HALF_YEAR", "END_OF_YEAR", "END_OF_PARTICULAR_MONTH" ], "description": "Rounding type." }, "value": { "description": "Month number (1-12), only for `END_OF_PARTICULAR_MONTH`. Nullable otherwise.", "oneOf": [ { "type": "integer", "minimum": 1, "maximum": 12 }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "END_OF_PARTICULAR_MONTH" } } }, "then": { "required": [ "value", "type" ], "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 12 } } } }, { "if": { "properties": { "type": { "not": { "const": "END_OF_PARTICULAR_MONTH" } } } }, "then": { "required": [ "type" ], "properties": { "value": { "type": "null" } } } } ] }, "EarningRuleEffectPointsExpirationCalendarExpiration": { "type": "object", "description": "Calendar expiration - points expire on fixed calendar dates (1 to 20 dates).", "properties": { "expiration_dates": { "type": "array", "minItems": 1, "maxItems": 20, "description": "Fixed expiration dates (day + month).", "items": { "$ref": "#/components/schemas/EarningRuleEffectPointsExpirationCalendarExpirationDate" } } }, "required": [ "expiration_dates" ], "additionalProperties": false }, "EarningRuleEffectPointsExpirationCalendarExpirationDate": { "type": "object", "description": "A calendar expiration date. The maximum `day` depends on `month`: 29 for February (month 2), 30 for April/June/September/November (4, 6, 9, 11), 31 for the remaining months.", "properties": { "day": { "type": "integer", "minimum": 1, "maximum": 31, "description": "Day of month (1-31; validated against the month length)." }, "month": { "type": "integer", "minimum": 1, "maximum": 12, "description": "Month number (1-12)." } }, "additionalProperties": false, "allOf": [ { "required": [ "day", "month" ] }, { "if": { "properties": { "month": { "const": 2 } } }, "then": { "properties": { "day": { "type": "integer", "minimum": 1, "maximum": 29 } } } }, { "if": { "properties": { "month": { "enum": [ 4, 6, 9, 11 ] } } }, "then": { "properties": { "day": { "type": "integer", "minimum": 1, "maximum": 30 } } } }, { "if": { "properties": { "month": { "enum": [ 1, 3, 5, 7, 8, 10, 12 ] } } }, "then": { "properties": { "day": { "type": "integer", "minimum": 1, "maximum": 31 } } } } ] }, "EarningRuleEffectPointsExpirationSlidingExpiration": { "type": "object", "description": "Sliding expiration - points expire after a period of member inactivity. At least one of `earning_activity`, `spending_activity` or `custom_activity` must be `true`. When `custom_activity` is `true`, `custom_activity_types` is required (1-10 unique items).", "properties": { "earning_activity": { "type": "boolean", "description": "Whether earning activity resets the expiration window." }, "spending_activity": { "type": "boolean", "description": "Whether spending activity resets the expiration window." }, "custom_activity": { "type": "boolean", "description": "Whether the listed custom activity types reset the expiration window." }, "custom_activity_types": { "description": "Custom activity type names. Required (1-10 unique items) when `custom_activity` is true. Nullable.", "oneOf": [ { "type": "array", "items": { "type": "string" } }, { "type": "null" } ] }, "period": { "$ref": "#/components/schemas/EarningRuleEffectPointsExpirationSlidingExpirationPeriod" } }, "additionalProperties": false, "allOf": [ { "required": [ "period" ] }, { "if": { "properties": { "custom_activity": { "const": true } } }, "then": { "required": [ "custom_activity_types" ], "properties": { "custom_activity_types": { "type": "array", "minItems": 1, "maxItems": 10, "uniqueItems": true, "items": { "type": "string" } } } } } ] }, "EarningRuleEffectPointsExpirationSlidingExpirationPeriod": { "type": "object", "description": "Sliding expiration inactivity period. The maximum `value` depends on `unit`: `DAY` - 90, `MONTH` - 12, `YEAR` - 1.", "properties": { "value": { "type": "integer", "minimum": 1, "description": "Period length. Maximum depends on `unit`: 90 for DAY, 12 for MONTH, 1 for YEAR." }, "unit": { "type": "string", "enum": [ "DAY", "MONTH", "YEAR" ], "description": "Period unit." } }, "additionalProperties": false, "allOf": [ { "required": [ "value", "unit" ] }, { "if": { "properties": { "unit": { "const": "DAY" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 90 } } } }, { "if": { "properties": { "unit": { "const": "MONTH" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 12 } } } }, { "if": { "properties": { "unit": { "const": "YEAR" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 1 } } } } ] }, "EarningRuleTierRules": { "type": "object", "description": "Tier requirements for an earning. With `NO_REQUIREMENTS`, `any_of` must be null/absent. With `ANY_OF`, `any_of` is required (at least one entry) and the member must be in any of the listed tiers to earn.", "properties": { "type": { "type": "string", "enum": [ "NO_REQUIREMENTS", "ANY_OF" ], "description": "Tier requirement type." }, "any_of": { "description": "Tier structure/tier combinations, any of which satisfies the requirement. Nullable.", "oneOf": [ { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/EarningRuleTierRulesAnyOfEntry" } }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "NO_REQUIREMENTS" } } }, "then": { "properties": { "any_of": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "ANY_OF" } } }, "then": { "required": [ "any_of" ], "properties": { "any_of": { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/EarningRuleTierRulesAnyOfEntry" } } } } } ] }, "EarningRuleTierRulesAnyOfEntry": { "type": "object", "description": "Tier structure with a list of qualifying tiers.", "properties": { "tier_structure_id": { "type": "string", "pattern": "^lts_[a-f0-9]+$", "description": "Tier structure ID (`lts_...`)." }, "tier_ids": { "type": "array", "minItems": 1, "description": "Qualifying tier IDs (`lt_...`).", "items": { "type": "string", "pattern": "^lt_[a-f0-9]+$" } } }, "required": [ "tier_structure_id", "tier_ids" ], "additionalProperties": false }, "EarningRuleValidityHours": { "type": "object", "description": "Hours during which the earning rule is active. With `ANY_TIME`, `daily` must be null/absent. With `DAILY`, `daily` is required (at least one entry).", "properties": { "type": { "type": "string", "enum": [ "DAILY", "ANY_TIME" ], "description": "Validity hours type." }, "daily": { "description": "Daily validity windows. Nullable.", "oneOf": [ { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/EarningRuleValidityDailyHours" } }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "ANY_TIME" } } }, "then": { "properties": { "daily": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "DAILY" } } }, "then": { "required": [ "daily" ], "properties": { "daily": { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/EarningRuleValidityDailyHours" } } } } } ] }, "EarningRuleValidityDailyHours": { "type": "object", "description": "Daily validity window on selected days of the week.", "properties": { "days_of_week": { "type": "array", "minItems": 1, "maxItems": 7, "uniqueItems": true, "description": "Days of week (0 = Sunday ... 6 = Saturday). Items must be unique.", "items": { "type": "integer", "minimum": 0, "maximum": 6 } }, "start_time": { "type": "string", "description": "Window start time in `HH:mm` format." }, "end_time": { "type": "string", "description": "Window end time in `HH:mm` format." } }, "required": [ "days_of_week", "start_time", "end_time" ], "additionalProperties": false }, "EarningRuleTriggerLimits": { "type": "object", "description": "Cooldown and frequency limits applied to the earning rule trigger.", "properties": { "cooldown": { "description": "Cooldown configuration. Nullable (defaults to `NO_COOLDOWN`).", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleTriggerLimitsCooldown" }, { "type": "null" } ] }, "frequency": { "description": "Frequency limit configuration. Nullable (defaults to `NO_LIMIT`).", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleTriggerLimitsFrequency" }, { "type": "null" } ] } }, "additionalProperties": false }, "EarningRuleTriggerLimitsCooldown": { "type": "object", "description": "Cooldown between consecutive triggers per member. With `NO_COOLDOWN`, `fixed_cooldown` must be null/absent. With `FIXED_COOLDOWN`, `fixed_cooldown` is required.", "properties": { "type": { "type": "string", "enum": [ "NO_COOLDOWN", "FIXED_COOLDOWN" ], "description": "Cooldown type." }, "fixed_cooldown": { "description": "Fixed cooldown configuration. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleTriggerLimitsCooldownFixedCooldown" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "NO_COOLDOWN" } } }, "then": { "properties": { "fixed_cooldown": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "FIXED_COOLDOWN" } } }, "then": { "required": [ "fixed_cooldown" ], "properties": { "fixed_cooldown": { "$ref": "#/components/schemas/EarningRuleTriggerLimitsCooldownFixedCooldown" } } } } ] }, "EarningRuleTriggerLimitsCooldownFixedCooldown": { "type": "object", "description": "Fixed cooldown period configuration.", "properties": { "period": { "$ref": "#/components/schemas/EarningRuleTriggerLimitsCooldownFixedCooldownPeriod" } }, "required": [ "period" ], "additionalProperties": false }, "EarningRuleTriggerLimitsCooldownFixedCooldownPeriod": { "type": "object", "description": "Cooldown period. The maximum `value` depends on `unit`: `HOUR` - 24, `DAY` - 90, `WEEK` - 52, `MONTH` - 12, `YEAR` - 1.", "properties": { "value": { "type": "integer", "minimum": 1, "description": "Period length. Maximum depends on `unit`: 24 for HOUR, 90 for DAY, 52 for WEEK, 12 for MONTH, 1 for YEAR." }, "unit": { "type": "string", "enum": [ "HOUR", "DAY", "WEEK", "MONTH", "YEAR" ], "description": "Period unit." } }, "additionalProperties": false, "allOf": [ { "required": [ "value", "unit" ] }, { "if": { "properties": { "unit": { "const": "HOUR" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 24 } } } }, { "if": { "properties": { "unit": { "const": "DAY" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 90 } } } }, { "if": { "properties": { "unit": { "const": "WEEK" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 52 } } } }, { "if": { "properties": { "unit": { "const": "MONTH" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 12 } } } }, { "if": { "properties": { "unit": { "const": "YEAR" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 1 } } } } ] }, "EarningRuleTriggerLimitsFrequency": { "type": "object", "description": "Frequency limit for triggers per member. With `NO_LIMIT`, `limits` must be null or an empty array. With `LIMITED`, `limits` is required and must contain exactly one limit.", "properties": { "type": { "type": "string", "enum": [ "NO_LIMIT", "LIMITED" ], "description": "Frequency limit type." }, "limits": { "description": "Frequency limits (at most one). Nullable.", "oneOf": [ { "type": "null" }, { "type": "array", "minItems": 0, "maxItems": 1, "items": { "$ref": "#/components/schemas/EarningRuleTriggerLimitsFrequencyLimit" } } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "NO_LIMIT" } } }, "then": { "properties": { "limits": { "oneOf": [ { "type": "array", "minItems": 0, "maxItems": 0, "items": { "$ref": "#/components/schemas/EarningRuleTriggerLimitsFrequencyLimit" } }, { "type": "null" } ] } } } }, { "if": { "properties": { "type": { "const": "LIMITED" } } }, "then": { "required": [ "limits" ], "properties": { "limits": { "type": "array", "minItems": 1, "maxItems": 1, "items": { "$ref": "#/components/schemas/EarningRuleTriggerLimitsFrequencyLimit" } } } } } ] }, "EarningRuleTriggerLimitsFrequencyLimit": { "type": "object", "description": "A single frequency limit. Currently only the `TIME_BASED` variant exists (discriminated by `type`), which requires `period` and `triggers`.", "required": [ "type" ], "properties": { "type": { "type": "string", "enum": [ "TIME_BASED" ], "description": "Frequency limit variant." } }, "oneOf": [ { "type": "object", "properties": { "type": { "const": "TIME_BASED" }, "period": { "$ref": "#/components/schemas/EarningRuleTriggerLimitsFrequencyLimitTimeBasedPeriod" }, "triggers": { "$ref": "#/components/schemas/EarningRuleTriggerLimitsFrequencyLimitTimeBasedTriggers" } }, "required": [ "period", "triggers" ], "additionalProperties": false } ] }, "EarningRuleTriggerLimitsFrequencyLimitTimeBasedPeriod": { "type": "object", "description": "Time-based frequency limit period. Currently only `CURRENT_PERIOD` is supported; when selected, `current_period` is required.", "properties": { "type": { "type": "string", "enum": [ "CURRENT_PERIOD" ], "description": "Period type." }, "current_period": { "description": "Current calendar period configuration. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleTriggerLimitsFrequencyLimitTimeBasedCurrentPeriod" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "CURRENT_PERIOD" } } }, "then": { "required": [ "current_period" ], "properties": { "current_period": { "$ref": "#/components/schemas/EarningRuleTriggerLimitsFrequencyLimitTimeBasedCurrentPeriod" } } } } ] }, "EarningRuleTriggerLimitsFrequencyLimitTimeBasedCurrentPeriod": { "type": "object", "description": "Current calendar period unit for the frequency limit.", "properties": { "unit": { "type": "string", "enum": [ "DAY", "WEEK", "MONTH", "QUARTER", "YEAR" ], "description": "Calendar period unit." } }, "required": [ "unit" ], "additionalProperties": false }, "EarningRuleTriggerLimitsFrequencyLimitTimeBasedTriggers": { "type": "object", "description": "Maximum number of triggers allowed within the period.", "properties": { "max": { "type": "integer", "minimum": 1, "description": "Maximum number of triggers per period." } }, "required": [ "max" ], "additionalProperties": false }, "EarningRuleEarningResponse": { "type": "object", "description": "An earning definition as returned by the API.", "properties": { "id": { "type": "string", "pattern": "^lernei_[a-f0-9]+$", "description": "Earning item ID (`lernei_...`)." }, "name": { "type": [ "string", "null" ], "maxLength": 200, "description": "Earning item name. Nullable." }, "rules": { "description": "Validation rules group. Absent when the earning has no rules.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleRulesGroup" }, { "type": "null" } ] }, "tier_rules": { "description": "Tier requirements. Defaults to `{ \"type\": \"NO_REQUIREMENTS\" }` when not explicitly configured.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleTierRules" }, { "type": "null" } ] }, "effects": { "type": "array", "description": "Effects applied when the rules match.", "items": { "$ref": "#/components/schemas/EarningRuleEffect" } } } }, "EarningRuleResponse": { "type": "object", "description": "Earning rule as returned by the API.", "properties": { "id": { "type": "string", "pattern": "^lern_[a-f0-9]+$", "description": "Earning rule ID (`lern_...`)." }, "name": { "type": "string", "maxLength": 200, "description": "Earning rule name." }, "status": { "type": "string", "enum": [ "DRAFT", "ACTIVE", "INACTIVE" ], "description": "Current status. `DELETED` also exists internally but deleted rules are excluded from API reads." }, "earnings": { "type": "array", "description": "Earning definitions of the rule.", "items": { "$ref": "#/components/schemas/EarningRuleEarningResponse" } }, "trigger": { "$ref": "#/components/schemas/EarningRuleTrigger" }, "error": { "description": "Default error configuration. Absent when not configured.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleError" }, { "type": "null" } ] }, "validity_hours": { "$ref": "#/components/schemas/EarningRuleValidityHours", "description": "Validity hours. Always present; defaults to `{ \"type\": \"ANY_TIME\" }`." }, "start_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date-time from which the rule is active. Nullable." }, "end_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date-time until which the rule is active. Nullable." }, "trigger_limits": { "description": "Cooldown and frequency limits. In responses, `frequency.limits` is always an array (empty for `NO_LIMIT`).", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleTriggerLimits" }, { "type": "null" } ] }, "metadata": { "$ref": "#/components/schemas/EarningRuleMetadata", "description": "Arbitrary key-value metadata. Always present (empty object when unset)." }, "created_at": { "type": "string", "format": "date-time", "description": "Creation timestamp (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last update timestamp (ISO 8601). Null when never updated." }, "object": { "type": "string", "const": "earning_rule", "description": "Object type marker. Always `earning_rule`." } } }, "EarningRuleListCursor": { "type": [ "object", "null" ], "description": "Pagination cursor. Null when there are no more results.", "properties": { "next": { "type": "string", "description": "Cursor ID to pass as the `cursor` query parameter to fetch the next page." }, "expires_at": { "type": "string", "format": "date-time", "description": "Cursor expiration timestamp." } } }, "EarningRuleListResponse": { "type": "object", "description": "Cursor-paginated list of earning rules.", "properties": { "data": { "type": "array", "description": "Earning rules on the current page.", "items": { "$ref": "#/components/schemas/EarningRuleResponse" } }, "cursor": { "$ref": "#/components/schemas/EarningRuleListCursor" }, "object": { "type": "string", "const": "list", "description": "Object type marker. Always `list`." } } }, "EarningRuleListFilters": { "type": "object", "description": "Filters for listing earning rules. Each field carries a required `conditions` object; condition values may be passed as a single string or as an array. Conditions not allowed for the field type are rejected.", "properties": { "junction": { "description": "How multiple field filters are combined. Defaults to AND behaviour. Nullable.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "ID filter. Allowed conditions: `$is`, `$is_not` (single value), `$in`, `$not_in` (up to 100 values). Values must match `^lern_[a-f0-9]+$`. Nullable.", "oneOf": [ { "type": "object", "required": [ "conditions" ], "additionalProperties": false, "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Exactly matches the value (single value).", "oneOf": [ { "type": "string", "pattern": "^lern_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^lern_[a-f0-9]+$" } } ] }, "$is_not": { "description": "Does not match the value (single value).", "oneOf": [ { "type": "string", "pattern": "^lern_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^lern_[a-f0-9]+$" } } ] }, "$in": { "description": "Matches any of the values (up to 100).", "oneOf": [ { "type": "string", "pattern": "^lern_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^lern_[a-f0-9]+$" } } ] }, "$not_in": { "description": "Matches none of the values (up to 100).", "oneOf": [ { "type": "string", "pattern": "^lern_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^lern_[a-f0-9]+$" } } ] } } } } }, { "type": "null" } ] }, "name": { "description": "Name filter (string type). Allowed conditions: `$is`, `$is_not`, `$contains`, `$not_contain`, `$starts_with`, `$ends_with` (single value), `$in`, `$not_in` (up to 10 values), `$has_value`, `$is_unknown`. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleStringFilterConditions" }, { "type": "null" } ] }, "status": { "description": "Status filter (enum type). Allowed conditions: `$is`, `$is_not` (single value), `$in`, `$not_in` (up to 10 values). Allowed values: `ACTIVE`, `INACTIVE`, `DRAFT`. Nullable.", "oneOf": [ { "type": "object", "required": [ "conditions" ], "additionalProperties": false, "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Exactly matches the value (single value).", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] } } ] }, "$is_not": { "description": "Does not match the value (single value).", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] } } ] }, "$in": { "description": "Matches any of the values (up to 10).", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] } } ] }, "$not_in": { "description": "Matches none of the values (up to 10).", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "ACTIVE", "INACTIVE", "DRAFT" ] } } ] } } } } }, { "type": "null" } ] }, "created_at": { "description": "Creation date filter. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleDateFilterConditions" }, { "type": "null" } ] } }, "additionalProperties": false }, "EarningRuleStringFilterConditions": { "type": "object", "description": "String field filter conditions. `$is`, `$is_not`, `$contains`, `$not_contain`, `$starts_with` and `$ends_with` take a single value (string or one-element array); `$in` and `$not_in` take up to 10 values; `$has_value` and `$is_unknown` are presence checks (value is ignored).", "required": [ "conditions" ], "additionalProperties": false, "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Exactly matches the value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } } ] }, "$is_not": { "description": "Does not match the value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } } ] }, "$contains": { "description": "Contains the substring.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } } ] }, "$not_contain": { "description": "Does not contain the substring.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } } ] }, "$starts_with": { "description": "Starts with the prefix.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } } ] }, "$ends_with": { "description": "Ends with the suffix.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } } ] }, "$in": { "description": "Matches any of the values (up to 10).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string" } } ] }, "$not_in": { "description": "Matches none of the values (up to 10).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string" } } ] }, "$has_value": { "description": "Field has a value (presence check).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 } ] }, "$is_unknown": { "description": "Field has no value (absence check).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 } ] } } } } }, "EarningRuleDateFilterConditions": { "type": "object", "description": "Date field filter conditions. `$before` and `$after` take a date string; `$is`, `$more_than` and `$less_than` take a non-negative integer number of days (relative comparison); `$has_value` and `$is_unknown` are presence checks.", "required": [ "conditions" ], "additionalProperties": false, "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$before": { "description": "Before the given date (single date string).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } } ] }, "$after": { "description": "After the given date (single date string).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } } ] }, "$is": { "description": "Exactly N days ago (non-negative integer).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } } ] }, "$more_than": { "description": "More than N days ago (non-negative integer).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } } ] }, "$less_than": { "description": "Less than N days ago (non-negative integer).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } } ] }, "$has_value": { "description": "Field has a value (presence check).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 } ] }, "$is_unknown": { "description": "Field has no value (absence check).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 } ] } } } } }, "EarningRuleActivitiesListFilters": { "type": "object", "description": "Filters for listing earning rule activities.", "properties": { "junction": { "description": "How multiple field filters are combined. Nullable.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Activity ID filter. Allowed conditions: `$is`, `$is_not` (single value), `$in`, `$not_in` (up to 100 values). Values must match `^laer_[a-f0-9]+$`. Nullable.", "oneOf": [ { "type": "object", "required": [ "conditions" ], "additionalProperties": false, "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Exactly matches the value (single value).", "oneOf": [ { "type": "string", "pattern": "^laer_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^laer_[a-f0-9]+$" } } ] }, "$is_not": { "description": "Does not match the value (single value).", "oneOf": [ { "type": "string", "pattern": "^laer_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^laer_[a-f0-9]+$" } } ] }, "$in": { "description": "Matches any of the values (up to 100).", "oneOf": [ { "type": "string", "pattern": "^laer_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^laer_[a-f0-9]+$" } } ] }, "$not_in": { "description": "Matches none of the values (up to 100).", "oneOf": [ { "type": "string", "pattern": "^laer_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^laer_[a-f0-9]+$" } } ] } } } } }, { "type": "null" } ] }, "type": { "description": "Activity type filter (enum type). Allowed conditions: `$is`, `$is_not` (single value), `$in`, `$not_in` (up to 10 values). Nullable.", "oneOf": [ { "type": "object", "required": [ "conditions" ], "additionalProperties": false, "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Exactly matches the value (single value).", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleActivityType" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "$ref": "#/components/schemas/EarningRuleActivityType" } } ] }, "$is_not": { "description": "Does not match the value (single value).", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleActivityType" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "$ref": "#/components/schemas/EarningRuleActivityType" } } ] }, "$in": { "description": "Matches any of the values (up to 10).", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleActivityType" }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "$ref": "#/components/schemas/EarningRuleActivityType" } } ] }, "$not_in": { "description": "Matches none of the values (up to 10).", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleActivityType" }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "$ref": "#/components/schemas/EarningRuleActivityType" } } ] } } } } }, { "type": "null" } ] }, "created_at": { "description": "Creation date filter. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleDateFilterConditions" }, { "type": "null" } ] } }, "additionalProperties": false }, "EarningRuleActivityType": { "type": "string", "description": "Earning rule activity type.", "enum": [ "vl.earning_rule.created", "vl.earning_rule.updated", "vl.earning_rule.deleted", "vl.earning_rule.activated", "vl.earning_rule.deactivated", "vl.earning_rule.drafted", "vl.earning_rule.assigned", "vl.earning_rule.unassigned" ] }, "EarningRuleActivitySource": { "type": "object", "description": "Origin of the activity.", "properties": { "channel": { "type": "string", "enum": [ "USER_PORTAL", "API", "CLIENT_API", "INTERNAL" ], "description": "Channel through which the change was made." }, "user": { "type": "object", "description": "User who made the change (present for USER_PORTAL channel).", "properties": { "id": { "type": "string", "description": "User ID." } } }, "api_key": { "type": "object", "description": "API key used to make the change (present for API/CLIENT_API channels).", "properties": { "name": { "type": "string", "description": "API key name." }, "app_id": { "type": "string", "description": "Application ID of the API key." }, "client_app_id": { "type": "string", "description": "Client application ID (for CLIENT_API keys)." } } } } }, "EarningRuleActivityResponse": { "type": "object", "description": "A single earning rule activity.", "properties": { "id": { "type": "string", "pattern": "^laer_[a-f0-9]+$", "description": "Activity ID (`laer_...`)." }, "earning_rule_id": { "type": "string", "pattern": "^lern_[a-f0-9]+$", "description": "ID of the earning rule the activity belongs to." }, "type": { "$ref": "#/components/schemas/EarningRuleActivityType" }, "data": { "type": "object", "description": "Activity payload. For created/updated/deleted/activated/deactivated/drafted activities it contains an `earning_rule` snapshot (the full earning rule object at the time of the change).", "additionalProperties": true }, "created_at": { "type": "string", "format": "date-time", "description": "Activity timestamp (ISO 8601)." }, "group_id": { "type": "string", "description": "Groups related activities recorded together." }, "source": { "$ref": "#/components/schemas/EarningRuleActivitySource", "description": "Origin of the activity. Absent when not recorded." } } }, "EarningRuleActivitiesListResponse": { "type": "object", "description": "Cursor-paginated list of earning rule activities.", "properties": { "data": { "type": "array", "description": "Activities on the current page.", "items": { "$ref": "#/components/schemas/EarningRuleActivityResponse" } }, "cursor": { "type": [ "object", "null" ], "description": "Pagination cursor. Null when there are no more results.", "properties": { "next": { "type": "string", "description": "Cursor ID to pass as the `cursor` query parameter (matches `^lcrsaer_[a-f0-9]+$`)." }, "expires_at": { "type": "string", "format": "date-time", "description": "Cursor expiration timestamp." } } }, "object": { "type": "string", "const": "list", "description": "Object type marker. Always `list`." } } }, "TierStructureCreateRequest": { "type": "object", "description": "Request body for creating a tier structure. No additional properties are allowed.", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Display name of the tier structure. Required." }, "type": { "type": "string", "enum": [ "POINT_BALANCE", "POINT_EARNED" ], "description": "Tier qualification tracking model. `POINT_BALANCE` qualifies members by their\ncurrent point balance; `POINT_EARNED` qualifies members by points earned within\na tracking period. Required." }, "point_balance": { "description": "Point balance tracking settings. Required (non-null) when `type` is\n`POINT_BALANCE`; must be null/omitted when `type` is `POINT_EARNED`.", "oneOf": [ { "$ref": "#/components/schemas/TierStructurePointBalanceUpsert" }, { "type": "null" } ] }, "point_earned": { "description": "Points earned tracking settings. Required (non-null) when `type` is\n`POINT_EARNED`; must be null/omitted when `type` is `POINT_BALANCE`.", "oneOf": [ { "$ref": "#/components/schemas/TierStructurePointEarnedUpsert" }, { "type": "null" } ] }, "expiration": { "description": "Tier membership expiration settings. If omitted, defaults to\n`{ \"type\": \"NO_EXPIRATION\" }`.", "oneOf": [ { "$ref": "#/components/schemas/TierStructureExpirationUpsert" }, { "type": "null" } ] }, "downgrade": { "description": "Downgrade behavior applied when tier membership expires. If omitted, defaults to\n`{ \"type\": \"NO_DOWNGRADE\" }`.", "oneOf": [ { "$ref": "#/components/schemas/TierStructureDowngradeUpsert" }, { "type": "null" } ] }, "metadata": { "description": "Free-form key/value object holding custom attributes.", "oneOf": [ { "type": "object" }, { "type": "null" } ] }, "status": { "type": "string", "enum": [ "DRAFT", "ACTIVE" ], "description": "Initial status of the tier structure. Defaults to `DRAFT` when omitted." } }, "additionalProperties": false, "allOf": [ { "required": [ "name", "type" ] }, { "if": { "properties": { "type": { "const": "POINT_EARNED" } } }, "then": { "required": [ "point_earned" ], "properties": { "point_earned": { "$ref": "#/components/schemas/TierStructurePointEarnedUpsert" }, "point_balance": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "POINT_BALANCE" } } }, "then": { "required": [ "point_balance" ], "properties": { "point_balance": { "$ref": "#/components/schemas/TierStructurePointBalanceUpsert" }, "point_earned": { "type": "null" } } } } ] }, "TierStructureUpdateRequest": { "type": "object", "description": "Request body for updating a tier structure. All properties are optional; no\nadditional properties are allowed. When the tier structure is not in `DRAFT`\nstatus, only `name` and `metadata` may be updated.", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Display name of the tier structure." }, "type": { "type": "string", "enum": [ "POINT_BALANCE", "POINT_EARNED" ], "description": "Tier qualification tracking model. If provided, the matching tracking settings\nobject (`point_balance` or `point_earned`) becomes required." }, "point_balance": { "description": "Point balance tracking settings. Required (non-null) when `type` is provided as\n`POINT_BALANCE`; must be null when `type` is provided as `POINT_EARNED`.", "oneOf": [ { "$ref": "#/components/schemas/TierStructurePointBalanceUpsert" }, { "type": "null" } ] }, "point_earned": { "description": "Points earned tracking settings. Required (non-null) when `type` is provided as\n`POINT_EARNED`; must be null when `type` is provided as `POINT_BALANCE`.", "oneOf": [ { "$ref": "#/components/schemas/TierStructurePointEarnedUpsert" }, { "type": "null" } ] }, "expiration": { "description": "Tier membership expiration settings.", "oneOf": [ { "$ref": "#/components/schemas/TierStructureExpirationUpsert" }, { "type": "null" } ] }, "downgrade": { "description": "Downgrade behavior applied when tier membership expires.", "oneOf": [ { "$ref": "#/components/schemas/TierStructureDowngradeUpsert" }, { "type": "null" } ] }, "metadata": { "description": "Free-form key/value object holding custom attributes.", "oneOf": [ { "type": "object" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "if": { "properties": { "type": { "const": "POINT_EARNED" } }, "required": [ "type" ] }, "then": { "required": [ "point_earned" ], "properties": { "point_earned": { "$ref": "#/components/schemas/TierStructurePointEarnedUpsert" }, "point_balance": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "POINT_BALANCE" } }, "required": [ "type" ] }, "then": { "required": [ "point_balance" ], "properties": { "point_balance": { "$ref": "#/components/schemas/TierStructurePointBalanceUpsert" }, "point_earned": { "type": "null" } } } } ] }, "TierStructurePointBalanceUpsert": { "type": "object", "description": "Point balance tracking settings. Members qualify for tiers based on the current\nbalance of the referenced card definition.", "properties": { "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "Identifier of the card definition whose point balance is tracked." } }, "required": [ "card_definition_id" ], "additionalProperties": false }, "TierStructurePointEarnedUpsert": { "type": "object", "description": "Points earned tracking settings. Members qualify for tiers based on points earned\non the referenced card definition within a tracking period.", "properties": { "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "Identifier of the card definition whose earned points are tracked." }, "period": { "$ref": "#/components/schemas/TierStructurePointEarnedPeriodUpsert", "description": "Tracking period during which earned points are accumulated." }, "type": { "type": "string", "enum": [ "IMMEDIATELY", "NEXT_TRACKING_PERIOD" ], "description": "When a tier change resulting from earned points takes effect: `IMMEDIATELY`\nor at the start of the `NEXT_TRACKING_PERIOD`." } }, "required": [ "card_definition_id", "period", "type" ], "additionalProperties": false }, "TierStructurePointEarnedPeriodUpsert": { "type": "object", "description": "Points earned tracking period. The maximum `value` depends on `unit`: 90 for\n`DAY`, 52 for `WEEK`, 12 for `MONTH`, 5 for `YEAR`.", "properties": { "value": { "type": "integer", "minimum": 1, "description": "Length of the tracking period, expressed in `unit` units. Minimum 1. Maximum\ndepends on `unit` (DAY: 90, WEEK: 52, MONTH: 12, YEAR: 5)." }, "unit": { "type": "string", "enum": [ "DAY", "WEEK", "MONTH", "YEAR" ], "description": "Unit of the tracking period." } }, "additionalProperties": false, "allOf": [ { "required": [ "value", "unit" ] }, { "if": { "properties": { "unit": { "const": "DAY" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 90 } } } }, { "if": { "properties": { "unit": { "const": "WEEK" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 52 } } } }, { "if": { "properties": { "unit": { "const": "MONTH" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 12 } } } }, { "if": { "properties": { "unit": { "const": "YEAR" } } }, "then": { "properties": { "value": { "type": "integer", "minimum": 1, "maximum": 5 } } } } ] }, "TierStructureExpirationUpsert": { "type": "object", "description": "Tier membership expiration settings. Exactly the sub-object matching `type` is\nrequired; the remaining sub-objects must be null/omitted.", "properties": { "type": { "type": "string", "enum": [ "NO_EXPIRATION", "SLIDING_EXPIRATION", "FIXED_DURATION", "CALENDAR_EXPIRATION" ], "description": "Expiration model for tier membership. Required." }, "fixed_duration": { "description": "Fixed duration expiration settings. Required (non-null) when `type` is\n`FIXED_DURATION`; must be null/omitted otherwise.", "oneOf": [ { "$ref": "#/components/schemas/TierStructureExpirationFixedDurationUpsert" }, { "type": "null" } ] }, "calendar_expiration": { "description": "Calendar expiration settings. Required (non-null) when `type` is\n`CALENDAR_EXPIRATION`; must be null/omitted otherwise.", "oneOf": [ { "$ref": "#/components/schemas/TierStructureExpirationCalendarExpirationUpsert" }, { "type": "null" } ] }, "sliding_expiration": { "description": "Sliding expiration settings. Required (non-null) when `type` is\n`SLIDING_EXPIRATION`; must be null/omitted otherwise.", "oneOf": [ { "$ref": "#/components/schemas/TierStructureExpirationSlidingExpirationUpsert" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "NO_EXPIRATION" } } }, "then": { "properties": { "fixed_duration": { "type": "null" }, "calendar_expiration": { "type": "null" }, "sliding_expiration": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "FIXED_DURATION" } } }, "then": { "required": [ "fixed_duration" ], "properties": { "fixed_duration": { "$ref": "#/components/schemas/TierStructureExpirationFixedDurationUpsert" }, "calendar_expiration": { "type": "null" }, "sliding_expiration": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "CALENDAR_EXPIRATION" } } }, "then": { "required": [ "calendar_expiration" ], "properties": { "fixed_duration": { "type": "null" }, "calendar_expiration": { "$ref": "#/components/schemas/TierStructureExpirationCalendarExpirationUpsert" }, "sliding_expiration": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "SLIDING_EXPIRATION" } } }, "then": { "required": [ "sliding_expiration" ], "properties": { "fixed_duration": { "type": "null" }, "calendar_expiration": { "type": "null" }, "sliding_expiration": { "$ref": "#/components/schemas/TierStructureExpirationSlidingExpirationUpsert" } } } } ] }, "TierStructureExpirationFixedDurationUpsert": { "type": "object", "description": "Fixed duration expiration settings. Tier membership expires after a fixed period.", "properties": { "period": { "$ref": "#/components/schemas/TierStructureExpirationFixedDurationPeriodUpsert", "description": "Duration after which the tier membership expires." } }, "required": [ "period" ], "additionalProperties": false }, "TierStructureExpirationFixedDurationPeriodUpsert": { "type": "object", "description": "Fixed duration expiration period.", "properties": { "value": { "type": "integer", "minimum": 1, "description": "Length of the expiration period, expressed in `unit` units. Minimum 1." }, "unit": { "type": "string", "enum": [ "DAY", "MONTH", "YEAR" ], "description": "Unit of the expiration period." } }, "required": [ "value", "unit" ], "additionalProperties": false }, "TierStructureExpirationCalendarExpirationUpsert": { "type": "object", "description": "Calendar expiration settings. Tier membership expires on fixed calendar dates.", "properties": { "calendar_dates": { "type": "array", "minItems": 1, "maxItems": 20, "description": "Calendar dates (day + month) on which tier membership expires. 1-20 items.", "items": { "$ref": "#/components/schemas/TierStructureExpirationCalendarDateUpsert" } } }, "required": [ "calendar_dates" ], "additionalProperties": false }, "TierStructureExpirationCalendarDateUpsert": { "type": "object", "description": "A recurring calendar date. The maximum `day` depends on `month`: 29 for February\n(month 2), 30 for April/June/September/November (months 4, 6, 9, 11), and 31 for\nthe remaining months.", "properties": { "day": { "type": "integer", "minimum": 1, "maximum": 31, "description": "Day of the month (1-31). Maximum depends on `month`: February allows up to 29;\nApril, June, September and November allow up to 30; other months allow up to 31." }, "month": { "type": "integer", "minimum": 1, "maximum": 12, "description": "Month of the year (1-12)." } }, "additionalProperties": false, "allOf": [ { "required": [ "day", "month" ] }, { "if": { "properties": { "month": { "const": 2 } } }, "then": { "properties": { "day": { "type": "integer", "minimum": 1, "maximum": 29 } } } }, { "if": { "properties": { "month": { "enum": [ 4, 6, 9, 11 ] } } }, "then": { "properties": { "day": { "type": "integer", "minimum": 1, "maximum": 30 } } } }, { "if": { "properties": { "month": { "enum": [ 1, 3, 5, 7, 8, 10, 12 ] } } }, "then": { "properties": { "day": { "type": "integer", "minimum": 1, "maximum": 31 } } } } ] }, "TierStructureExpirationSlidingExpirationUpsert": { "type": "object", "description": "Sliding expiration settings. Tier membership expiration slides forward on the\nconfigured member activities.", "properties": { "earning_activity": { "type": "boolean", "description": "Whether point earning activity extends the tier membership." }, "spending_activity": { "type": "boolean", "description": "Whether point spending activity extends the tier membership." }, "custom_activity": { "type": "boolean", "description": "Whether custom activities extend the tier membership." }, "custom_activity_types": { "type": "array", "maxItems": 10, "uniqueItems": true, "description": "Custom activity type names that extend the tier membership. Up to 10 unique\nitems. Defaults to an empty array when omitted.", "items": { "type": "string", "minLength": 1, "description": "Custom activity type name." } }, "period": { "description": "Sliding period after the last qualifying activity. Required (may be null).", "oneOf": [ { "$ref": "#/components/schemas/TierStructureExpirationSlidingExpirationPeriodUpsert" }, { "type": "null" } ] } }, "required": [ "period" ], "additionalProperties": false }, "TierStructureExpirationSlidingExpirationPeriodUpsert": { "type": "object", "description": "Sliding expiration period.", "properties": { "value": { "type": "integer", "minimum": 1, "description": "Length of the sliding period, expressed in `unit` units. Minimum 1." }, "unit": { "type": "string", "enum": [ "DAY", "MONTH", "YEAR" ], "description": "Unit of the sliding period." } }, "required": [ "value", "unit" ], "additionalProperties": false }, "TierStructureDowngradeUpsert": { "type": "object", "description": "Downgrade settings. Controls how members are moved to lower tiers on expiration.\nWhen `type` is `NO_DOWNGRADE`, `grace_period` must be null/omitted.", "properties": { "type": { "type": "string", "enum": [ "MULTI_LEVEL", "SINGLE_LEVEL", "NO_DOWNGRADE" ], "description": "Downgrade model. `MULTI_LEVEL` allows dropping multiple tiers at once,\n`SINGLE_LEVEL` drops one tier at a time, `NO_DOWNGRADE` disables downgrades.\nRequired." }, "grace_period": { "description": "Grace period before the downgrade takes effect. Must be null/omitted when\n`type` is `NO_DOWNGRADE`.", "oneOf": [ { "$ref": "#/components/schemas/TierStructureDowngradeGracePeriodUpsert" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "NO_DOWNGRADE" } } }, "then": { "properties": { "grace_period": { "type": "null" } } } } ] }, "TierStructureDowngradeGracePeriodUpsert": { "type": "object", "description": "Downgrade grace period.", "properties": { "value": { "type": "integer", "minimum": 1, "description": "Length of the grace period, expressed in `unit` units. Minimum 1." }, "unit": { "type": "string", "enum": [ "DAY", "MONTH", "YEAR" ], "description": "Unit of the grace period." }, "round_up": { "type": "boolean", "description": "Whether the grace period end is rounded up to the end of the unit." } }, "required": [ "value", "unit" ], "additionalProperties": false }, "TierCreateRequest": { "type": "object", "description": "Request body for creating a tier. No additional properties are allowed.", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Display name of the tier. Required." }, "qualification_rules": { "description": "Rules determining which members qualify for this tier. Required.", "oneOf": [ { "$ref": "#/components/schemas/TierQualificationRulesUpsert" } ] }, "downgrade": { "description": "Tier-level downgrade behavior. If omitted, defaults to `{ \"type\": \"INHERIT\" }`\n(inherits the tier structure downgrade settings).", "oneOf": [ { "$ref": "#/components/schemas/TierDowngradeUpsert" }, { "type": "null" } ] }, "metadata": { "description": "Free-form key/value object holding custom attributes.", "oneOf": [ { "type": "object" }, { "type": "null" } ] } }, "required": [ "name", "qualification_rules" ], "additionalProperties": false }, "TierUpdateRequest": { "type": "object", "description": "Request body for updating a tier. All properties are optional; no additional\nproperties are allowed. When the parent tier structure is not in `DRAFT` status,\nonly `name` and `metadata` may be updated.", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Display name of the tier." }, "qualification_rules": { "description": "Rules determining which members qualify for this tier.", "oneOf": [ { "$ref": "#/components/schemas/TierQualificationRulesUpsert" }, { "type": "null" } ] }, "downgrade": { "description": "Tier-level downgrade behavior.", "oneOf": [ { "$ref": "#/components/schemas/TierDowngradeUpsert" }, { "type": "null" } ] }, "metadata": { "description": "Free-form key/value object holding custom attributes.", "oneOf": [ { "type": "object" }, { "type": "null" } ] } }, "additionalProperties": false }, "TierQualificationRulesUpsert": { "type": "object", "description": "Tier qualification rules. When `type` is `POINTS`, `points` is required and\n`segment` must be null/omitted; when `type` is `POINTS_AND_SEGMENT`, both `points`\nand `segment` are required.", "properties": { "type": { "type": "string", "enum": [ "POINTS", "POINTS_AND_SEGMENT" ], "description": "Qualification model. `POINTS` qualifies by point thresholds only;\n`POINTS_AND_SEGMENT` additionally requires membership in a customer segment.\nRequired." }, "points": { "description": "Point thresholds for the tier. Required (non-null) when `type` is `POINTS`\nor `POINTS_AND_SEGMENT`.", "oneOf": [ { "$ref": "#/components/schemas/TierQualificationRulesPointsUpsert" }, { "type": "null" } ] }, "segment": { "description": "Customer segment reference. Required (non-null) when `type` is\n`POINTS_AND_SEGMENT`; must be null/omitted when `type` is `POINTS`.", "oneOf": [ { "$ref": "#/components/schemas/TierQualificationRulesSegmentUpsert" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "POINTS" } } }, "then": { "required": [ "points" ], "properties": { "points": { "$ref": "#/components/schemas/TierQualificationRulesPointsUpsert" }, "segment": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "POINTS_AND_SEGMENT" } } }, "then": { "required": [ "points", "segment" ], "properties": { "points": { "$ref": "#/components/schemas/TierQualificationRulesPointsUpsert" }, "segment": { "$ref": "#/components/schemas/TierQualificationRulesSegmentUpsert" } } } } ] }, "TierQualificationRulesPointsUpsert": { "type": "object", "description": "Point thresholds for tier qualification. Values must be non-negative numbers\nbetween 0 and 1,000,000,000.", "properties": { "min_value": { "type": "number", "minimum": 0, "maximum": 1000000000, "description": "Minimum number of points required to qualify for the tier. Required." }, "max_value": { "type": "number", "minimum": 0, "maximum": 1000000000, "description": "Optional upper bound of points for the tier." } }, "required": [ "min_value" ], "additionalProperties": false }, "TierQualificationRulesSegmentUpsert": { "type": "object", "description": "Customer segment reference for tier qualification.", "properties": { "id": { "type": "string", "minLength": 1, "description": "Identifier of the customer segment." } }, "required": [ "id" ], "additionalProperties": false }, "TierDowngradeUpsert": { "type": "object", "description": "Tier-level downgrade behavior.", "properties": { "type": { "type": "string", "enum": [ "INHERIT", "NO_DOWNGRADE" ], "description": "`INHERIT` uses the parent tier structure downgrade settings; `NO_DOWNGRADE`\ndisables downgrades from this tier. Required." } }, "required": [ "type" ], "additionalProperties": false }, "TierStructure": { "type": "object", "description": "Tier structure resource.", "properties": { "id": { "type": "string", "pattern": "^lts_[a-f0-9]+$", "description": "Unique tier structure identifier." }, "name": { "type": "string", "description": "Display name of the tier structure." }, "type": { "type": "string", "enum": [ "POINT_BALANCE", "POINT_EARNED" ], "description": "Tier qualification tracking model." }, "point_balance": { "$ref": "#/components/schemas/TierStructurePointBalance", "description": "Point balance tracking settings. Present only when `type` is `POINT_BALANCE`;\nomitted otherwise." }, "point_earned": { "$ref": "#/components/schemas/TierStructurePointEarned", "description": "Points earned tracking settings. Present only when `type` is `POINT_EARNED`;\nomitted otherwise." }, "expiration": { "$ref": "#/components/schemas/TierStructureExpiration", "description": "Tier membership expiration settings." }, "downgrade": { "$ref": "#/components/schemas/TierStructureDowngrade", "description": "Downgrade behavior applied when tier membership expires." }, "metadata": { "type": "object", "description": "Free-form key/value object holding custom attributes. Defaults to `{}`." }, "status": { "type": "string", "enum": [ "DRAFT", "ACTIVE", "INACTIVE", "DELETED" ], "description": "Current lifecycle status of the tier structure." }, "created_at": { "type": "string", "format": "date-time", "description": "Creation timestamp (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last update timestamp (ISO 8601), or null if never updated." }, "object": { "type": "string", "const": "tier_structure", "description": "Object type discriminator. Always `tier_structure`." } }, "required": [ "id", "name", "type", "expiration", "downgrade", "metadata", "status", "created_at", "updated_at", "object" ] }, "TierStructurePointBalance": { "type": "object", "description": "Point balance tracking settings.", "properties": { "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "Identifier of the card definition whose point balance is tracked." } } }, "TierStructurePointEarned": { "type": "object", "description": "Points earned tracking settings.", "properties": { "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "Identifier of the card definition whose earned points are tracked." }, "period": { "$ref": "#/components/schemas/TierStructurePointEarnedPeriod", "description": "Tracking period during which earned points are accumulated." }, "type": { "type": "string", "enum": [ "IMMEDIATELY", "NEXT_TRACKING_PERIOD" ], "description": "When a tier change resulting from earned points takes effect." } } }, "TierStructurePointEarnedPeriod": { "type": "object", "description": "Points earned tracking period.", "properties": { "value": { "type": "integer", "description": "Length of the tracking period, expressed in `unit` units." }, "unit": { "type": "string", "enum": [ "DAY", "WEEK", "MONTH", "YEAR" ], "description": "Unit of the tracking period." } } }, "TierStructureExpiration": { "type": "object", "description": "Tier membership expiration settings. Only the sub-object matching `type` is\npresent; the others are omitted.", "properties": { "type": { "type": "string", "enum": [ "NO_EXPIRATION", "SLIDING_EXPIRATION", "FIXED_DURATION", "CALENDAR_EXPIRATION" ], "description": "Expiration model for tier membership." }, "fixed_duration": { "$ref": "#/components/schemas/TierStructureExpirationFixedDuration", "description": "Fixed duration settings. Present only when `type` is `FIXED_DURATION`." }, "calendar_expiration": { "$ref": "#/components/schemas/TierStructureExpirationCalendarExpiration", "description": "Calendar expiration settings. Present only when `type` is `CALENDAR_EXPIRATION`." }, "sliding_expiration": { "$ref": "#/components/schemas/TierStructureExpirationSlidingExpiration", "description": "Sliding expiration settings. Present only when `type` is `SLIDING_EXPIRATION`." } } }, "TierStructureExpirationFixedDuration": { "type": "object", "description": "Fixed duration expiration settings.", "properties": { "period": { "$ref": "#/components/schemas/TierStructureExpirationPeriod", "description": "Duration after which the tier membership expires." } } }, "TierStructureExpirationCalendarExpiration": { "type": "object", "description": "Calendar expiration settings.", "properties": { "calendar_dates": { "type": "array", "description": "Calendar dates on which tier membership expires.", "items": { "$ref": "#/components/schemas/TierStructureExpirationCalendarDate" } } } }, "TierStructureExpirationCalendarDate": { "type": "object", "description": "A recurring calendar date.", "properties": { "day": { "type": "integer", "minimum": 1, "maximum": 31, "description": "Day of the month (1-31)." }, "month": { "type": "integer", "minimum": 1, "maximum": 12, "description": "Month of the year (1-12)." } } }, "TierStructureExpirationSlidingExpiration": { "type": "object", "description": "Sliding expiration settings.", "properties": { "earning_activity": { "type": "boolean", "description": "Whether point earning activity extends the tier membership." }, "spending_activity": { "type": "boolean", "description": "Whether point spending activity extends the tier membership." }, "custom_activity": { "type": "boolean", "description": "Whether custom activities extend the tier membership." }, "custom_activity_types": { "type": "array", "description": "Custom activity type names that extend the tier membership.", "items": { "type": "string", "description": "Custom activity type name." } }, "period": { "$ref": "#/components/schemas/TierStructureExpirationPeriod", "description": "Sliding period after the last qualifying activity." } } }, "TierStructureExpirationPeriod": { "type": "object", "description": "Expiration period. The same shape is used for fixed duration and sliding\nexpiration periods.", "properties": { "value": { "type": "integer", "description": "Length of the period, expressed in `unit` units." }, "unit": { "type": "string", "enum": [ "DAY", "MONTH", "YEAR" ], "description": "Unit of the period." } } }, "TierStructureDowngrade": { "type": "object", "description": "Downgrade settings.", "properties": { "type": { "type": "string", "enum": [ "MULTI_LEVEL", "SINGLE_LEVEL", "NO_DOWNGRADE" ], "description": "Downgrade model." }, "grace_period": { "$ref": "#/components/schemas/TierStructureDowngradeGracePeriod", "description": "Grace period before the downgrade takes effect. Omitted when not configured." } } }, "TierStructureDowngradeGracePeriod": { "type": "object", "description": "Downgrade grace period.", "properties": { "value": { "type": "integer", "description": "Length of the grace period, expressed in `unit` units." }, "unit": { "type": "string", "enum": [ "DAY", "MONTH", "YEAR" ], "description": "Unit of the grace period." }, "round_up": { "type": "boolean", "description": "Whether the grace period end is rounded up to the end of the unit." } } }, "TierStructureListResponse": { "type": "object", "description": "Cursor-paginated list of tier structures.", "properties": { "data": { "type": "array", "description": "Tier structures on the current page.", "items": { "$ref": "#/components/schemas/TierStructure" } }, "cursor": { "description": "Pagination cursor for fetching the next page, or null when there are no more\nresults.", "oneOf": [ { "type": "object", "properties": { "next": { "type": "string", "pattern": "^lcrsts_[a-f0-9]+$", "description": "Cursor id to pass as the `cursor` query parameter for the next page." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp after which the cursor expires (ISO 8601)." } } }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type discriminator. Always `list`." } }, "required": [ "data", "cursor", "object" ] }, "Tier": { "type": "object", "description": "Tier resource.", "properties": { "id": { "type": "string", "pattern": "^lt_[a-f0-9]+$", "description": "Unique tier identifier." }, "tier_structure_id": { "type": "string", "pattern": "^lts_[a-f0-9]+$", "description": "Identifier of the parent tier structure." }, "name": { "type": "string", "description": "Display name of the tier." }, "qualification_rules": { "$ref": "#/components/schemas/TierQualificationRules", "description": "Rules determining which members qualify for this tier." }, "downgrade": { "$ref": "#/components/schemas/TierDowngrade", "description": "Tier-level downgrade behavior. Always present; when the tier has no downgrade\nconfigured, an empty object (no `type`) is returned." }, "metadata": { "type": "object", "description": "Free-form key/value object holding custom attributes. Defaults to `{}`." }, "created_at": { "type": "string", "format": "date-time", "description": "Creation timestamp (ISO 8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Last update timestamp (ISO 8601), or null if never updated." }, "object": { "type": "string", "const": "tier", "description": "Object type discriminator. Always `tier`." } }, "required": [ "id", "tier_structure_id", "name", "downgrade", "metadata", "created_at", "updated_at", "object" ] }, "TierQualificationRules": { "type": "object", "description": "Tier qualification rules.", "properties": { "type": { "type": "string", "enum": [ "POINTS", "POINTS_AND_SEGMENT" ], "description": "Qualification model." }, "points": { "$ref": "#/components/schemas/TierQualificationRulesPoints", "description": "Point thresholds for the tier. Omitted when not configured." }, "segment": { "$ref": "#/components/schemas/TierQualificationRulesSegment", "description": "Customer segment reference. Present only when `type` is `POINTS_AND_SEGMENT`." } } }, "TierQualificationRulesPoints": { "type": "object", "description": "Point thresholds for tier qualification.", "properties": { "min_value": { "type": "number", "description": "Minimum number of points required to qualify for the tier." }, "max_value": { "type": "number", "description": "Optional upper bound of points for the tier. Omitted when not set." } } }, "TierQualificationRulesSegment": { "type": "object", "description": "Customer segment reference.", "properties": { "id": { "type": "string", "description": "Identifier of the customer segment." } } }, "TierDowngrade": { "type": "object", "description": "Tier-level downgrade behavior.", "properties": { "type": { "type": "string", "enum": [ "INHERIT", "NO_DOWNGRADE" ], "description": "Downgrade model. Omitted when the tier has no downgrade configured." } } }, "TierListResponse": { "type": "object", "description": "Cursor-paginated list of tiers.", "properties": { "data": { "type": "array", "description": "Tiers on the current page.", "items": { "$ref": "#/components/schemas/Tier" } }, "cursor": { "description": "Pagination cursor for fetching the next page, or null when there are no more\nresults.", "oneOf": [ { "type": "object", "properties": { "next": { "type": "string", "pattern": "^lcrst_[a-f0-9]+$", "description": "Cursor id to pass as the `cursor` query parameter for the next page." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp after which the cursor expires (ISO 8601)." } } }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type discriminator. Always `list`." } }, "required": [ "data", "cursor", "object" ] }, "TierStructureActivity": { "type": "object", "description": "A tier structure activity record.", "properties": { "id": { "type": "string", "pattern": "^lats_[a-f0-9]+$", "description": "Unique activity identifier." }, "type": { "type": "string", "enum": [ "vl.tier_structure.created", "vl.tier_structure.updated", "vl.tier_structure.deleted", "vl.tier_structure.activated", "vl.tier_structure.deactivated", "vl.tier_structure.drafted", "vl.tier_structure.assigned", "vl.tier_structure.unassigned", "vl.tier_structure.tier.created", "vl.tier_structure.tier.updated", "vl.tier_structure.tier.deleted" ], "description": "Activity type." }, "data": { "$ref": "#/components/schemas/TierStructureActivityData", "description": "Activity payload snapshot." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp of when the activity occurred (ISO 8601)." }, "group_id": { "type": "string", "description": "Identifier grouping related activities that were produced by the same operation.\nOmitted when not set." }, "source": { "$ref": "#/components/schemas/TierStructureActivitySource", "description": "Origin of the activity (channel, user, API key). Omitted when not set." }, "tier_structure_id": { "type": "string", "pattern": "^lts_[a-f0-9]+$", "description": "Identifier of the tier structure the activity relates to." } }, "required": [ "id", "type", "data", "created_at", "tier_structure_id" ] }, "TierStructureActivityData": { "type": "object", "description": "Activity payload. Always contains a `tier_structure` snapshot. For\n`vl.tier_structure.tier.*` activities it additionally contains a `tier` snapshot;\nfor `vl.tier_structure.assigned`/`vl.tier_structure.unassigned` activities it\nadditionally contains `program` and `program_tier_structure` snapshots.", "properties": { "tier_structure": { "$ref": "#/components/schemas/TierStructure", "description": "Snapshot of the tier structure at the time of the activity." }, "tier": { "$ref": "#/components/schemas/Tier", "description": "Snapshot of the tier. Present only for `vl.tier_structure.tier.created`,\n`vl.tier_structure.tier.updated` and `vl.tier_structure.tier.deleted` activities." }, "program": { "type": "object", "description": "Snapshot of the loyalty program (documented in the Programs domain).\nPresent only for `vl.tier_structure.assigned` and\n`vl.tier_structure.unassigned` activities." }, "program_tier_structure": { "type": "object", "description": "Snapshot of the program-to-tier-structure assignment (documented in the\nPrograms domain). Present only for `vl.tier_structure.assigned` and\n`vl.tier_structure.unassigned` activities." } }, "required": [ "tier_structure" ] }, "TierStructureActivitySource": { "type": "object", "description": "Origin of an activity.", "properties": { "channel": { "type": "string", "enum": [ "USER_PORTAL", "API", "CLIENT_API", "INTERNAL" ], "description": "Channel through which the activity was triggered." }, "user": { "type": "object", "description": "User who triggered the activity. Omitted when not applicable.", "properties": { "id": { "type": "string", "description": "Identifier of the user." } } }, "api_key": { "type": "object", "description": "API key used to trigger the activity. Omitted when not applicable.", "properties": { "name": { "type": "string", "description": "Name of the API key." }, "app_id": { "type": "string", "description": "Application id of the API key." }, "client_app_id": { "type": "string", "description": "Client application id of the API key." } } } } }, "TierStructureActivityListResponse": { "type": "object", "description": "Cursor-paginated list of tier structure activities.", "properties": { "data": { "type": "array", "description": "Activities on the current page.", "items": { "$ref": "#/components/schemas/TierStructureActivity" } }, "cursor": { "description": "Pagination cursor for fetching the next page, or null when there are no more\nresults.", "oneOf": [ { "type": "object", "properties": { "next": { "type": "string", "pattern": "^lcrsats_[a-f0-9]+$", "description": "Cursor id to pass as the `cursor` query parameter for the next page." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp after which the cursor expires (ISO 8601)." } } }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type discriminator. Always `list`." } }, "required": [ "data", "cursor", "object" ] }, "TierStructureListFilters": { "type": "object", "description": "Filters for the tier structures list. Each field accepts a `conditions` object;\neach filter field may also be null.", "properties": { "junction": { "description": "Logical junction combining the field filters. Defaults to AND semantics.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by tier structure id (ID field conditions, pattern `^lts_[a-f0-9]+$`).", "oneOf": [ { "$ref": "#/components/schemas/TierStructureFilterIdField" }, { "type": "null" } ] }, "name": { "description": "Filter by tier structure name (string field conditions).", "oneOf": [ { "$ref": "#/components/schemas/TierStructureFilterStringField" }, { "type": "null" } ] }, "type": { "description": "Filter by tier structure type (enum field conditions).", "oneOf": [ { "$ref": "#/components/schemas/TierStructureFilterTypeField" }, { "type": "null" } ] }, "status": { "description": "Filter by tier structure status (enum field conditions).", "oneOf": [ { "$ref": "#/components/schemas/TierStructureFilterStatusField" }, { "type": "null" } ] }, "created_at": { "description": "Filter by creation date (date field conditions).", "oneOf": [ { "$ref": "#/components/schemas/TierStructureFilterDateField" }, { "type": "null" } ] } }, "additionalProperties": false }, "TierStructureActivityListFilters": { "type": "object", "description": "Filters for the tier structure activities list. Each field accepts a `conditions`\nobject; each filter field may also be null.", "properties": { "junction": { "description": "Logical junction combining the field filters. Defaults to AND semantics.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by activity id (ID field conditions, pattern `^lats_[a-f0-9]+$`).", "oneOf": [ { "$ref": "#/components/schemas/TierStructureActivityFilterIdField" }, { "type": "null" } ] }, "type": { "description": "Filter by activity type (enum field conditions).", "oneOf": [ { "$ref": "#/components/schemas/TierStructureActivityFilterTypeField" }, { "type": "null" } ] }, "created_at": { "description": "Filter by activity creation date (date field conditions).", "oneOf": [ { "$ref": "#/components/schemas/TierStructureFilterDateField" }, { "type": "null" } ] } }, "additionalProperties": false }, "TierStructureFilterIdField": { "type": "object", "description": "ID field filter for tier structure ids. Allowed conditions: `$is`, `$is_not`,\n`$in`, `$not_in`. Each condition accepts a single string or an array of strings\nmatching `^lts_[a-f0-9]+$`.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "description": "Condition operators applied to the field.", "properties": { "$is": { "description": "Matches when the field equals the given id.", "oneOf": [ { "type": "string", "pattern": "^lts_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } }, { "type": "null" } ] }, "$is_not": { "description": "Matches when the field does not equal the given id.", "oneOf": [ { "type": "string", "pattern": "^lts_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } }, { "type": "null" } ] }, "$in": { "description": "Matches when the field equals any of the given ids (up to 100).", "oneOf": [ { "type": "string", "pattern": "^lts_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } }, { "type": "null" } ] }, "$not_in": { "description": "Matches when the field equals none of the given ids (up to 100).", "oneOf": [ { "type": "string", "pattern": "^lts_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^lts_[a-f0-9]+$" } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "TierStructureActivityFilterIdField": { "type": "object", "description": "ID field filter for tier structure activity ids. Allowed conditions: `$is`,\n`$is_not`, `$in`, `$not_in`. Each condition accepts a single string or an array\nof strings matching `^lats_[a-f0-9]+$`.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "description": "Condition operators applied to the field.", "properties": { "$is": { "description": "Matches when the field equals the given id.", "oneOf": [ { "type": "string", "pattern": "^lats_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^lats_[a-f0-9]+$" } }, { "type": "null" } ] }, "$is_not": { "description": "Matches when the field does not equal the given id.", "oneOf": [ { "type": "string", "pattern": "^lats_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^lats_[a-f0-9]+$" } }, { "type": "null" } ] }, "$in": { "description": "Matches when the field equals any of the given ids (up to 100).", "oneOf": [ { "type": "string", "pattern": "^lats_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^lats_[a-f0-9]+$" } }, { "type": "null" } ] }, "$not_in": { "description": "Matches when the field equals none of the given ids (up to 100).", "oneOf": [ { "type": "string", "pattern": "^lats_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^lats_[a-f0-9]+$" } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "TierStructureFilterStringField": { "type": "object", "description": "String field filter. Allowed conditions: `$is`, `$is_not`, `$contains`,\n`$not_contain`, `$starts_with`, `$ends_with`, `$in`, `$not_in`, `$has_value`,\n`$is_unknown`. Each condition accepts a single string or an array of strings.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "description": "Condition operators applied to the field.", "properties": { "$is": { "description": "Matches when the field equals the given value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$is_not": { "description": "Matches when the field does not equal the given value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$contains": { "description": "Matches when the field contains the given substring.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$not_contain": { "description": "Matches when the field does not contain the given substring.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$starts_with": { "description": "Matches when the field starts with the given prefix.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$ends_with": { "description": "Matches when the field ends with the given suffix.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$in": { "description": "Matches when the field equals any of the given values (up to 10).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string" } }, { "type": "null" } ] }, "$not_in": { "description": "Matches when the field equals none of the given values (up to 10).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string" } }, { "type": "null" } ] }, "$has_value": { "description": "Matches when the field has any value. The value of this condition is ignored.", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] }, "$is_unknown": { "description": "Matches when the field has no value. The value of this condition is ignored.", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "TierStructureFilterTypeField": { "type": "object", "description": "Enum field filter for tier structure `type`. Allowed conditions: `$is`, `$is_not`,\n`$in`, `$not_in`. Allowed values: `POINT_BALANCE`, `POINT_EARNED`.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "description": "Condition operators applied to the field.", "properties": { "$is": { "description": "Matches when the field equals the given value.", "oneOf": [ { "type": "string", "enum": [ "POINT_BALANCE", "POINT_EARNED" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "POINT_BALANCE", "POINT_EARNED" ] } }, { "type": "null" } ] }, "$is_not": { "description": "Matches when the field does not equal the given value.", "oneOf": [ { "type": "string", "enum": [ "POINT_BALANCE", "POINT_EARNED" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "POINT_BALANCE", "POINT_EARNED" ] } }, { "type": "null" } ] }, "$in": { "description": "Matches when the field equals any of the given values (up to 10).", "oneOf": [ { "type": "string", "enum": [ "POINT_BALANCE", "POINT_EARNED" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "POINT_BALANCE", "POINT_EARNED" ] } }, { "type": "null" } ] }, "$not_in": { "description": "Matches when the field equals none of the given values (up to 10).", "oneOf": [ { "type": "string", "enum": [ "POINT_BALANCE", "POINT_EARNED" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "POINT_BALANCE", "POINT_EARNED" ] } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "TierStructureFilterStatusField": { "type": "object", "description": "Enum field filter for tier structure `status`. Allowed conditions: `$is`,\n`$is_not`, `$in`, `$not_in`. Allowed values: `DRAFT`, `ACTIVE`, `INACTIVE`,\n`DELETED`.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "description": "Condition operators applied to the field.", "properties": { "$is": { "description": "Matches when the field equals the given value.", "oneOf": [ { "type": "string", "enum": [ "DRAFT", "ACTIVE", "INACTIVE", "DELETED" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "DRAFT", "ACTIVE", "INACTIVE", "DELETED" ] } }, { "type": "null" } ] }, "$is_not": { "description": "Matches when the field does not equal the given value.", "oneOf": [ { "type": "string", "enum": [ "DRAFT", "ACTIVE", "INACTIVE", "DELETED" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "DRAFT", "ACTIVE", "INACTIVE", "DELETED" ] } }, { "type": "null" } ] }, "$in": { "description": "Matches when the field equals any of the given values (up to 10).", "oneOf": [ { "type": "string", "enum": [ "DRAFT", "ACTIVE", "INACTIVE", "DELETED" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "DRAFT", "ACTIVE", "INACTIVE", "DELETED" ] } }, { "type": "null" } ] }, "$not_in": { "description": "Matches when the field equals none of the given values (up to 10).", "oneOf": [ { "type": "string", "enum": [ "DRAFT", "ACTIVE", "INACTIVE", "DELETED" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "DRAFT", "ACTIVE", "INACTIVE", "DELETED" ] } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "TierStructureActivityFilterTypeField": { "type": "object", "description": "Enum field filter for activity `type`. Allowed conditions: `$is`, `$is_not`,\n`$in`, `$not_in`. Allowed values are the tier structure activity types.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "description": "Condition operators applied to the field.", "properties": { "$is": { "description": "Matches when the field equals the given value.", "oneOf": [ { "type": "string", "enum": [ "vl.tier_structure.created", "vl.tier_structure.updated", "vl.tier_structure.deleted", "vl.tier_structure.activated", "vl.tier_structure.deactivated", "vl.tier_structure.drafted", "vl.tier_structure.assigned", "vl.tier_structure.unassigned", "vl.tier_structure.tier.created", "vl.tier_structure.tier.updated", "vl.tier_structure.tier.deleted" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "vl.tier_structure.created", "vl.tier_structure.updated", "vl.tier_structure.deleted", "vl.tier_structure.activated", "vl.tier_structure.deactivated", "vl.tier_structure.drafted", "vl.tier_structure.assigned", "vl.tier_structure.unassigned", "vl.tier_structure.tier.created", "vl.tier_structure.tier.updated", "vl.tier_structure.tier.deleted" ] } }, { "type": "null" } ] }, "$is_not": { "description": "Matches when the field does not equal the given value.", "oneOf": [ { "type": "string", "enum": [ "vl.tier_structure.created", "vl.tier_structure.updated", "vl.tier_structure.deleted", "vl.tier_structure.activated", "vl.tier_structure.deactivated", "vl.tier_structure.drafted", "vl.tier_structure.assigned", "vl.tier_structure.unassigned", "vl.tier_structure.tier.created", "vl.tier_structure.tier.updated", "vl.tier_structure.tier.deleted" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "vl.tier_structure.created", "vl.tier_structure.updated", "vl.tier_structure.deleted", "vl.tier_structure.activated", "vl.tier_structure.deactivated", "vl.tier_structure.drafted", "vl.tier_structure.assigned", "vl.tier_structure.unassigned", "vl.tier_structure.tier.created", "vl.tier_structure.tier.updated", "vl.tier_structure.tier.deleted" ] } }, { "type": "null" } ] }, "$in": { "description": "Matches when the field equals any of the given values (up to 10).", "oneOf": [ { "type": "string", "enum": [ "vl.tier_structure.created", "vl.tier_structure.updated", "vl.tier_structure.deleted", "vl.tier_structure.activated", "vl.tier_structure.deactivated", "vl.tier_structure.drafted", "vl.tier_structure.assigned", "vl.tier_structure.unassigned", "vl.tier_structure.tier.created", "vl.tier_structure.tier.updated", "vl.tier_structure.tier.deleted" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "vl.tier_structure.created", "vl.tier_structure.updated", "vl.tier_structure.deleted", "vl.tier_structure.activated", "vl.tier_structure.deactivated", "vl.tier_structure.drafted", "vl.tier_structure.assigned", "vl.tier_structure.unassigned", "vl.tier_structure.tier.created", "vl.tier_structure.tier.updated", "vl.tier_structure.tier.deleted" ] } }, { "type": "null" } ] }, "$not_in": { "description": "Matches when the field equals none of the given values (up to 10).", "oneOf": [ { "type": "string", "enum": [ "vl.tier_structure.created", "vl.tier_structure.updated", "vl.tier_structure.deleted", "vl.tier_structure.activated", "vl.tier_structure.deactivated", "vl.tier_structure.drafted", "vl.tier_structure.assigned", "vl.tier_structure.unassigned", "vl.tier_structure.tier.created", "vl.tier_structure.tier.updated", "vl.tier_structure.tier.deleted" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "vl.tier_structure.created", "vl.tier_structure.updated", "vl.tier_structure.deleted", "vl.tier_structure.activated", "vl.tier_structure.deactivated", "vl.tier_structure.drafted", "vl.tier_structure.assigned", "vl.tier_structure.unassigned", "vl.tier_structure.tier.created", "vl.tier_structure.tier.updated", "vl.tier_structure.tier.deleted" ] } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "TierStructureFilterDateField": { "type": "object", "description": "Date field filter. Allowed conditions: `$before`, `$after`, `$is`, `$more_than`,\n`$less_than`, `$has_value`, `$is_unknown`. `$before`/`$after` accept valid date\nstrings; `$is`/`$more_than`/`$less_than` accept non-negative integer values.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "description": "Condition operators applied to the field.", "properties": { "$before": { "description": "Matches when the field is before the given date. Value must be a valid date string.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$after": { "description": "Matches when the field is after the given date. Value must be a valid date string.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$is": { "description": "Matches by relative value. A non-negative integer.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$more_than": { "description": "Matches by relative value (greater than). A non-negative integer.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$less_than": { "description": "Matches by relative value (less than). A non-negative integer.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$has_value": { "description": "Matches when the field has any value. The value of this condition is ignored.", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] }, "$is_unknown": { "description": "Matches when the field has no value. The value of this condition is ignored.", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "BenefitCreateRequest": { "type": "object", "description": "Request body for creating a benefit. Exactly one type-specific configuration object\nis required, matching the `type`; the remaining type-specific properties must be\nomitted or null.", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Benefit name. Must be unique within the project." }, "type": { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "MATERIAL", "DIGITAL" ], "description": "Benefit type. Determines which configuration object is required." }, "status": { "type": "string", "enum": [ "DRAFT", "ACTIVE" ], "description": "Initial status of the benefit. Defaults to `DRAFT` when omitted." }, "points": { "description": "Fixed points configuration. Required when `type` is `POINTS`, must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/BenefitPoints" }, { "type": "null" } ] }, "points_proportional": { "description": "Proportional points configuration. Required when `type` is `POINTS_PROPORTIONAL`, must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportional" }, { "type": "null" } ] }, "material": { "description": "Material (physical product/SKU) configuration. Required when `type` is `MATERIAL`, must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/BenefitMaterial" }, { "type": "null" } ] }, "digital": { "description": "Digital (campaign-based) configuration. Required when `type` is `DIGITAL`, must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/BenefitDigital" }, { "type": "null" } ] }, "stock": { "description": "Stock configuration. Defaults to `{ \"type\": \"UNLIMITED\" }` when omitted.", "oneOf": [ { "$ref": "#/components/schemas/BenefitStock" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "name", "type" ] }, { "if": { "properties": { "type": { "const": "POINTS" } } }, "then": { "required": [ "points" ], "properties": { "points": { "$ref": "#/components/schemas/BenefitPoints" }, "points_proportional": { "type": "null" }, "material": { "type": "null" }, "digital": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "POINTS_PROPORTIONAL" } } }, "then": { "required": [ "points_proportional" ], "properties": { "points": { "type": "null" }, "points_proportional": { "$ref": "#/components/schemas/BenefitPointsProportional" }, "material": { "type": "null" }, "digital": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "MATERIAL" } } }, "then": { "required": [ "material" ], "properties": { "points": { "type": "null" }, "points_proportional": { "type": "null" }, "material": { "$ref": "#/components/schemas/BenefitMaterial" }, "digital": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "DIGITAL" } } }, "then": { "required": [ "digital" ], "properties": { "points": { "type": "null" }, "points_proportional": { "type": "null" }, "material": { "type": "null" }, "digital": { "$ref": "#/components/schemas/BenefitDigital" } } } } ] }, "BenefitUpdateRequest": { "type": "object", "description": "Request body for updating a benefit. All properties are optional; omitted properties keep\ntheir current values. When the benefit is `ACTIVE`, only `name` and `stock` may be updated.\nAfter the update, the type-specific configuration must stay consistent with the (possibly\nupdated) `type`.", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Benefit name. Must be unique within the project." }, "type": { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "MATERIAL", "DIGITAL" ], "description": "Benefit type. Determines which configuration object is required." }, "points": { "description": "Fixed points configuration (for `type` `POINTS`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitPoints" }, { "type": "null" } ] }, "points_proportional": { "description": "Proportional points configuration (for `type` `POINTS_PROPORTIONAL`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportional" }, { "type": "null" } ] }, "material": { "description": "Material (physical product/SKU) configuration (for `type` `MATERIAL`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitMaterial" }, { "type": "null" } ] }, "digital": { "description": "Digital (campaign-based) configuration (for `type` `DIGITAL`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitDigital" }, { "type": "null" } ] }, "stock": { "description": "Stock configuration.", "oneOf": [ { "$ref": "#/components/schemas/BenefitStock" }, { "type": "null" } ] } }, "additionalProperties": false }, "BenefitPoints": { "type": "object", "description": "Fixed points effect - adds a fixed amount of points to a card of the given card definition.", "properties": { "value": { "type": "integer", "minimum": 0, "maximum": 9007199254740991, "description": "Number of points to add." }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "ID of the card definition whose cards receive the points. The card definition must exist and be ACTIVE." } }, "required": [ "value", "card_definition_id" ], "additionalProperties": false }, "BenefitPointsProportional": { "type": "object", "description": "Proportional points effect - points are calculated from an order amount, order items,\nor a metadata property. Exactly one calculation source object (`order`, `customer`,\n`custom_event`, or `order_items`) is required, determined by `calculation_type`;\nthe remaining source properties must be omitted or null.", "properties": { "calculation_type": { "type": "string", "enum": [ "PRE_DISCOUNT_ORDER_AMOUNT", "POST_DISCOUNT_ORDER_AMOUNT", "PRE_DISCOUNT_ORDER_ITEMS_AMOUNT", "POST_DISCOUNT_ORDER_ITEMS_AMOUNT", "ORDER_ITEMS_QUANTITY", "ORDER_METADATA_VALUE", "CUSTOMER_METADATA_VALUE", "CUSTOM_EVENT_METADATA_VALUE" ], "description": "How the points are calculated:\n- `PRE_DISCOUNT_ORDER_AMOUNT` - points per every specified order amount before discounts (requires `order.amount`)\n- `POST_DISCOUNT_ORDER_AMOUNT` - points per every specified order amount after discounts (requires `order.total_amount`)\n- `PRE_DISCOUNT_ORDER_ITEMS_AMOUNT` - points per every specified amount spent on selected products before discounts (requires `order_items.amount`)\n- `POST_DISCOUNT_ORDER_ITEMS_AMOUNT` - points per every specified amount spent on selected products after discounts (requires `order_items.subtotal_amount`)\n- `ORDER_ITEMS_QUANTITY` - points per every specified quantity of selected products, excluding free items (requires `order_items.quantity`)\n- `ORDER_METADATA_VALUE` - points per every specified value in the order metadata (requires `order.metadata`)\n- `CUSTOMER_METADATA_VALUE` - points per every specified value in the customer metadata (requires `customer.metadata`)\n- `CUSTOM_EVENT_METADATA_VALUE` - points per every specified value in the custom event metadata (requires `custom_event.metadata`)" }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "ID of the card definition whose cards receive the points. The card definition must exist and be ACTIVE." }, "order": { "description": "Order-based calculation configuration (for `PRE_DISCOUNT_ORDER_AMOUNT`, `POST_DISCOUNT_ORDER_AMOUNT`, `ORDER_METADATA_VALUE`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalOrder" }, { "type": "null" } ] }, "customer": { "description": "Customer-metadata-based calculation configuration (for `CUSTOMER_METADATA_VALUE`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalCustomer" }, { "type": "null" } ] }, "custom_event": { "description": "Custom-event-metadata-based calculation configuration (for `CUSTOM_EVENT_METADATA_VALUE`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalCustomEvent" }, { "type": "null" } ] }, "order_items": { "description": "Order-items-based calculation configuration (for `PRE_DISCOUNT_ORDER_ITEMS_AMOUNT`, `POST_DISCOUNT_ORDER_ITEMS_AMOUNT`, `ORDER_ITEMS_QUANTITY`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalOrderItems" }, { "type": "null" } ] } }, "required": [ "calculation_type", "card_definition_id" ], "additionalProperties": false, "allOf": [ { "if": { "properties": { "calculation_type": { "const": "PRE_DISCOUNT_ORDER_AMOUNT" } } }, "then": { "required": [ "order" ], "properties": { "order": { "type": "object", "required": [ "amount" ] }, "customer": { "type": "null" }, "custom_event": { "type": "null" }, "order_items": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "POST_DISCOUNT_ORDER_AMOUNT" } } }, "then": { "required": [ "order" ], "properties": { "order": { "type": "object", "required": [ "total_amount" ] }, "customer": { "type": "null" }, "custom_event": { "type": "null" }, "order_items": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "ORDER_METADATA_VALUE" } } }, "then": { "required": [ "order" ], "properties": { "order": { "type": "object", "required": [ "metadata" ] }, "customer": { "type": "null" }, "custom_event": { "type": "null" }, "order_items": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "CUSTOMER_METADATA_VALUE" } } }, "then": { "required": [ "customer" ], "properties": { "customer": { "$ref": "#/components/schemas/BenefitPointsProportionalCustomer" }, "order": { "type": "null" }, "custom_event": { "type": "null" }, "order_items": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "CUSTOM_EVENT_METADATA_VALUE" } } }, "then": { "required": [ "custom_event" ], "properties": { "custom_event": { "$ref": "#/components/schemas/BenefitPointsProportionalCustomEvent" }, "order": { "type": "null" }, "customer": { "type": "null" }, "order_items": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "PRE_DISCOUNT_ORDER_ITEMS_AMOUNT" } } }, "then": { "required": [ "order_items" ], "properties": { "order_items": { "type": "object", "required": [ "amount" ] }, "order": { "type": "null" }, "customer": { "type": "null" }, "custom_event": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "POST_DISCOUNT_ORDER_ITEMS_AMOUNT" } } }, "then": { "required": [ "order_items" ], "properties": { "order_items": { "type": "object", "required": [ "subtotal_amount" ] }, "order": { "type": "null" }, "customer": { "type": "null" }, "custom_event": { "type": "null" } } } }, { "if": { "properties": { "calculation_type": { "const": "ORDER_ITEMS_QUANTITY" } } }, "then": { "required": [ "order_items" ], "properties": { "order_items": { "type": "object", "required": [ "quantity" ] }, "order": { "type": "null" }, "customer": { "type": "null" }, "custom_event": { "type": "null" } } } } ] }, "BenefitPointsProportionalOrder": { "type": "object", "description": "Order-based proportional calculation. Provide the property matching the `calculation_type`.", "properties": { "amount": { "description": "Points per every specified pre-discount order amount (for `PRE_DISCOUNT_ORDER_AMOUNT`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalEvery" } ] }, "total_amount": { "description": "Points per every specified post-discount order amount (for `POST_DISCOUNT_ORDER_AMOUNT`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalEvery" } ] }, "metadata": { "description": "Points per every specified value of an order metadata property (for `ORDER_METADATA_VALUE`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalMetadata" } ] } }, "additionalProperties": false }, "BenefitPointsProportionalCustomer": { "type": "object", "description": "Customer-metadata-based proportional calculation.", "properties": { "metadata": { "description": "Points per every specified value of a customer metadata property.", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalMetadata" } ] } }, "required": [ "metadata" ], "additionalProperties": false }, "BenefitPointsProportionalCustomEvent": { "type": "object", "description": "Custom-event-metadata-based proportional calculation.", "properties": { "metadata": { "description": "Points per every specified value of a custom event metadata property.", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalMetadata" } ] } }, "required": [ "metadata" ], "additionalProperties": false }, "BenefitPointsProportionalOrderItems": { "type": "object", "description": "Order-items-based proportional calculation. Provide the property matching the `calculation_type`.", "properties": { "amount": { "description": "Points per every specified pre-discount amount spent on the selected items (for `PRE_DISCOUNT_ORDER_ITEMS_AMOUNT`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalOrderItemsCalculation" } ] }, "subtotal_amount": { "description": "Points per every specified post-discount amount spent on the selected items (for `POST_DISCOUNT_ORDER_ITEMS_AMOUNT`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalOrderItemsCalculation" } ] }, "quantity": { "description": "Points per every specified quantity of the selected items, excluding free items (for `ORDER_ITEMS_QUANTITY`).", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalOrderItemsCalculation" } ] } }, "additionalProperties": false }, "BenefitPointsProportionalEvery": { "type": "object", "description": "Ratio definition - `value` points for every `every` units.", "properties": { "every": { "type": "integer", "minimum": 1, "maximum": 9007199254740991, "description": "Unit step (e.g. order amount in cents) for which `value` points are granted." }, "value": { "type": "number", "minimum": 0, "maximum": 9007199254740991, "description": "Number of points granted per `every` units." } }, "required": [ "every", "value" ], "additionalProperties": false }, "BenefitPointsProportionalMetadata": { "type": "object", "description": "Metadata-based ratio definition - `value` points for every `every` units of the metadata property.", "properties": { "every": { "type": "integer", "minimum": 1, "maximum": 9007199254740991, "description": "Unit step of the metadata property value for which `value` points are granted." }, "value": { "type": "number", "minimum": 0, "maximum": 9007199254740991, "description": "Number of points granted per `every` units." }, "property": { "type": "string", "minLength": 1, "description": "Name of the metadata property used for the calculation." } }, "required": [ "every", "value", "property" ], "additionalProperties": false }, "BenefitPointsProportionalOrderItemsCalculation": { "type": "object", "description": "Order-items ratio definition with the list of applicable products/SKUs/collections.", "properties": { "every": { "type": "integer", "minimum": 1, "maximum": 9007199254740991, "description": "Unit step (amount or quantity) for which `value` points are granted." }, "value": { "type": "number", "minimum": 0, "maximum": 9007199254740991, "description": "Number of points granted per `every` units." }, "applicable_to": { "type": "array", "minItems": 1, "description": "Products, SKUs, or product collections the calculation applies to.", "items": { "$ref": "#/components/schemas/BenefitPointsProportionalApplicableTo" } } }, "required": [ "every", "value", "applicable_to" ], "additionalProperties": false }, "BenefitPointsProportionalApplicableTo": { "type": "object", "description": "A single applicability rule. Exactly one of `product`, `sku`, or `products_collection`\nis required, matching the `type`; the other two must be omitted or null.", "properties": { "type": { "type": "string", "enum": [ "product", "sku", "products_collection" ], "description": "Type of the referenced object." }, "product": { "description": "Product reference. Required when `type` is `product`, must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalApplicableToProduct" }, { "type": "null" } ] }, "sku": { "description": "SKU reference. Required when `type` is `sku`, must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalApplicableToSku" }, { "type": "null" } ] }, "products_collection": { "description": "Products collection reference. Required when `type` is `products_collection`, must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportionalApplicableToProductsCollection" }, { "type": "null" } ] } }, "required": [ "type" ], "additionalProperties": false, "allOf": [ { "if": { "properties": { "type": { "const": "product" } } }, "then": { "required": [ "product" ], "properties": { "product": { "$ref": "#/components/schemas/BenefitPointsProportionalApplicableToProduct" }, "sku": { "type": "null" }, "products_collection": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "sku" } } }, "then": { "required": [ "sku" ], "properties": { "sku": { "$ref": "#/components/schemas/BenefitPointsProportionalApplicableToSku" }, "product": { "type": "null" }, "products_collection": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "products_collection" } } }, "then": { "required": [ "products_collection" ], "properties": { "products_collection": { "$ref": "#/components/schemas/BenefitPointsProportionalApplicableToProductsCollection" }, "product": { "type": "null" }, "sku": { "type": "null" } } } } ] }, "BenefitPointsProportionalApplicableToProduct": { "type": "object", "description": "Product reference.", "properties": { "id": { "type": "string", "pattern": "^prod_[a-f0-9]+", "description": "Product ID, prefixed with `prod_`." } }, "required": [ "id" ], "additionalProperties": false }, "BenefitPointsProportionalApplicableToSku": { "type": "object", "description": "SKU reference.", "properties": { "id": { "type": "string", "pattern": "^sku_[a-f0-9]+", "description": "SKU ID, prefixed with `sku_`." } }, "required": [ "id" ], "additionalProperties": false }, "BenefitPointsProportionalApplicableToProductsCollection": { "type": "object", "description": "Products collection reference.", "properties": { "id": { "type": "string", "pattern": "^pc_[a-zA-Z0-9]+", "description": "Products collection ID, prefixed with `pc_`." } }, "required": [ "id" ], "additionalProperties": false }, "BenefitMaterial": { "type": "object", "description": "Material benefit - a physical product or SKU. Exactly one of `product` or `sku` is\nrequired, matching the `type`; the other must be omitted or null.", "properties": { "type": { "type": "string", "enum": [ "PRODUCT", "SKU" ], "description": "Whether the benefit is a whole product or a specific SKU." }, "product": { "description": "Product reference. Required when `type` is `PRODUCT`, must be null otherwise. The product must exist.", "oneOf": [ { "$ref": "#/components/schemas/BenefitMaterialProduct" }, { "type": "null" } ] }, "sku": { "description": "SKU reference. Required when `type` is `SKU`, must be null otherwise. The SKU must exist under the given product.", "oneOf": [ { "$ref": "#/components/schemas/BenefitMaterialSKU" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "PRODUCT" } } }, "then": { "required": [ "product" ], "properties": { "product": { "$ref": "#/components/schemas/BenefitMaterialProduct" }, "sku": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "SKU" } } }, "then": { "required": [ "sku" ], "properties": { "sku": { "$ref": "#/components/schemas/BenefitMaterialSKU" }, "product": { "type": "null" } } } } ] }, "BenefitMaterialProduct": { "type": "object", "description": "Product reference for a material benefit.", "properties": { "id": { "type": "string", "pattern": "^prod_[a-f0-9]+", "description": "Product ID, prefixed with `prod_`." } }, "required": [ "id" ], "additionalProperties": false }, "BenefitMaterialSKU": { "type": "object", "description": "SKU reference for a material benefit.", "properties": { "product_id": { "type": "string", "pattern": "^prod_[a-f0-9]+", "description": "ID of the product the SKU belongs to, prefixed with `prod_`." }, "id": { "type": "string", "pattern": "^sku_[a-f0-9]+", "description": "SKU ID, prefixed with `sku_`." } }, "required": [ "product_id", "id" ], "additionalProperties": false }, "BenefitDigital": { "type": "object", "description": "Digital benefit - a reward sourced from a Voucherify campaign. Exactly one of\n`gift_vouchers` or `discount_coupons` is required, matching the `type`; the other must\nbe omitted or null. The referenced campaign must exist and its campaign type must match\nthe benefit's digital type.", "properties": { "type": { "type": "string", "enum": [ "GIFT_VOUCHERS", "DISCOUNT_COUPONS" ], "description": "Type of the digital reward." }, "gift_vouchers": { "description": "Gift vouchers configuration. Required when `type` is `GIFT_VOUCHERS`, must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/BenefitDigitalGiftVouchers" }, { "type": "null" } ] }, "discount_coupons": { "description": "Discount coupons configuration. Required when `type` is `DISCOUNT_COUPONS`, must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/BenefitDigitalDiscountCoupons" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "DISCOUNT_COUPONS" } } }, "then": { "required": [ "discount_coupons" ], "properties": { "discount_coupons": { "$ref": "#/components/schemas/BenefitDigitalDiscountCoupons" }, "gift_vouchers": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "GIFT_VOUCHERS" } } }, "then": { "required": [ "gift_vouchers" ], "properties": { "gift_vouchers": { "$ref": "#/components/schemas/BenefitDigitalGiftVouchers" }, "discount_coupons": { "type": "null" } } } } ] }, "BenefitDigitalGiftVouchers": { "type": "object", "description": "Gift vouchers digital benefit configuration.", "properties": { "campaign_id": { "type": "string", "pattern": "^camp_[a-zA-Z0-9]+", "description": "ID of the GIFT_VOUCHERS campaign the vouchers are sourced from, prefixed with `camp_`." }, "balance": { "type": "number", "minimum": 0, "maximum": 9007199254740991, "description": "Balance loaded onto the gift voucher." } }, "required": [ "campaign_id", "balance" ], "additionalProperties": false }, "BenefitDigitalDiscountCoupons": { "type": "object", "description": "Discount coupons digital benefit configuration.", "properties": { "campaign_id": { "type": "string", "pattern": "^camp_[a-zA-Z0-9]+", "description": "ID of the DISCOUNT_COUPONS campaign the coupons are sourced from, prefixed with `camp_`." } }, "required": [ "campaign_id" ], "additionalProperties": false }, "BenefitStock": { "type": "object", "description": "Stock configuration of the benefit. When `type` is `LIMITED` the `limited` object is\nrequired; when `type` is `UNLIMITED` the `limited` object must be omitted or null.", "properties": { "type": { "type": "string", "enum": [ "UNLIMITED", "LIMITED" ], "description": "Whether the benefit has unlimited or limited stock." }, "limited": { "description": "Limited stock configuration. Required when `type` is `LIMITED`, must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/BenefitStockLimited" }, { "type": "null" } ] } }, "required": [ "type" ], "additionalProperties": false, "allOf": [ { "if": { "properties": { "type": { "const": "UNLIMITED" } } }, "then": { "properties": { "limited": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "LIMITED" } } }, "then": { "required": [ "limited" ], "properties": { "limited": { "$ref": "#/components/schemas/BenefitStockLimited" } } } } ] }, "BenefitStockLimited": { "type": "object", "description": "Limited stock configuration.", "properties": { "quantity": { "type": "integer", "minimum": 0, "maximum": 9007199254740991, "description": "Remaining stock quantity." } }, "required": [ "quantity" ], "additionalProperties": false }, "Benefit": { "type": "object", "description": "A benefit object. Exactly one type-specific configuration object\n(`points`, `points_proportional`, `material`, or `digital`) is present, matching the `type`;\nthe others are omitted.", "properties": { "id": { "type": "string", "pattern": "^lben_[a-f0-9]+$", "description": "Unique benefit ID, prefixed with `lben_`." }, "name": { "type": "string", "description": "Benefit name, unique within the project." }, "type": { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "MATERIAL", "DIGITAL" ], "description": "Benefit type." }, "status": { "type": "string", "enum": [ "DRAFT", "ACTIVE", "DELETED" ], "description": "Current benefit status. `DELETED` appears only in the response of the delete endpoint and in activity snapshots." }, "stock": { "description": "Stock configuration. Omitted when not set.", "oneOf": [ { "$ref": "#/components/schemas/BenefitStock" } ] }, "points": { "description": "Fixed points configuration. Present only when `type` is `POINTS`.", "oneOf": [ { "$ref": "#/components/schemas/BenefitPoints" } ] }, "points_proportional": { "description": "Proportional points configuration. Present only when `type` is `POINTS_PROPORTIONAL`.", "oneOf": [ { "$ref": "#/components/schemas/BenefitPointsProportional" } ] }, "material": { "description": "Material configuration. Present only when `type` is `MATERIAL`.", "oneOf": [ { "$ref": "#/components/schemas/BenefitMaterial" } ] }, "digital": { "description": "Digital configuration. Present only when `type` is `DIGITAL`.", "oneOf": [ { "$ref": "#/components/schemas/BenefitDigital" } ] }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp of when the benefit was created, in ISO 8601 format." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Timestamp of the last update, in ISO 8601 format. Null when the benefit was never updated." }, "object": { "type": "string", "const": "benefit", "description": "Type of the object. Always `benefit`." } }, "required": [ "id", "name", "type", "status", "created_at", "object" ] }, "BenefitListResponse": { "type": "object", "description": "Cursor-paginated list of benefits.", "properties": { "data": { "type": "array", "description": "Benefits matching the query, in the requested order.", "items": { "$ref": "#/components/schemas/Benefit" } }, "cursor": { "description": "Pagination cursor. Null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/BenefitListCursor" }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Type of the object. Always `list`." } }, "required": [ "data", "cursor", "object" ] }, "BenefitListCursor": { "type": "object", "description": "Pagination cursor pointing to the next page of results.", "properties": { "next": { "type": "string", "description": "Cursor ID to pass as the `cursor` query parameter to fetch the next page." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp after which the cursor expires." } }, "required": [ "next" ] }, "BenefitActivity": { "type": "object", "description": "A single benefit activity.", "properties": { "id": { "type": "string", "pattern": "^laben_[a-f0-9]+$", "description": "Unique activity ID, prefixed with `laben_`." }, "type": { "type": "string", "enum": [ "vl.benefit.created", "vl.benefit.updated", "vl.benefit.deleted", "vl.benefit.activated", "vl.benefit.drafted" ], "description": "Type of the recorded activity." }, "data": { "$ref": "#/components/schemas/BenefitActivityData" }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp of when the activity was recorded, in ISO 8601 format." }, "group_id": { "type": "string", "description": "ID grouping activities recorded within the same operation." }, "source": { "description": "Origin of the activity. Omitted when unknown.", "oneOf": [ { "$ref": "#/components/schemas/BenefitActivitySource" } ] }, "benefit_id": { "type": "string", "pattern": "^lben_[a-f0-9]+$", "description": "ID of the benefit the activity relates to." } }, "required": [ "id", "type", "data", "created_at", "benefit_id" ] }, "BenefitActivityData": { "type": "object", "description": "Activity payload containing a snapshot of the benefit at the time of the activity.", "properties": { "benefit": { "$ref": "#/components/schemas/Benefit" } }, "required": [ "benefit" ] }, "BenefitActivitySource": { "type": "object", "description": "Origin of the activity.", "properties": { "channel": { "type": "string", "enum": [ "USER_PORTAL", "API", "CLIENT_API", "INTERNAL" ], "description": "Channel the activity originated from." }, "user": { "description": "User who triggered the activity. Present for user-originated activities.", "oneOf": [ { "$ref": "#/components/schemas/BenefitActivitySourceUser" } ] }, "api_key": { "description": "API key used to trigger the activity. Present for API-originated activities.", "oneOf": [ { "$ref": "#/components/schemas/BenefitActivitySourceApiKey" } ] } } }, "BenefitActivitySourceUser": { "type": "object", "description": "User who triggered the activity.", "properties": { "id": { "type": "string", "description": "User ID." } } }, "BenefitActivitySourceApiKey": { "type": "object", "description": "API key used to trigger the activity.", "properties": { "name": { "type": "string", "description": "Name of the API key." }, "app_id": { "type": "string", "description": "Application ID of the API key." }, "client_app_id": { "type": "string", "description": "Client application ID (for client-side API keys)." } } }, "BenefitActivityListResponse": { "type": "object", "description": "Cursor-paginated list of benefit activities.", "properties": { "data": { "type": "array", "description": "Activities matching the query, in the requested order.", "items": { "$ref": "#/components/schemas/BenefitActivity" } }, "cursor": { "description": "Pagination cursor. Null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/BenefitListCursor" }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Type of the object. Always `list`." } }, "required": [ "data", "cursor", "object" ] }, "BenefitListFilters": { "type": "object", "description": "Filters for the benefits list. Each field accepts a `conditions` object with at least\none condition. Conditions of multiple fields are combined with the `junction`.", "properties": { "junction": { "description": "How conditions of multiple fields are combined. Defaults to `AND`.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by benefit ID.\nAllowed conditions: `$is`, `$is_not`, `$in`, `$not_in`. Values must match `^lben_[a-f0-9]+$`.\n`$is`/`$is_not` accept a single value (string or 1-element array); `$in`/`$not_in`\naccept up to 100 values.", "oneOf": [ { "$ref": "#/components/schemas/BenefitIdFilterConditions" }, { "type": "null" } ] }, "name": { "description": "Filter by benefit name.\nAllowed conditions: `$is`, `$is_not`, `$contains`, `$not_contain`, `$starts_with`,\n`$ends_with`, `$in`, `$not_in`, `$has_value`, `$is_unknown`. `$in`/`$not_in` accept\nup to 10 values; the other value conditions accept a single value (string or\n1-element array); `$has_value`/`$is_unknown` are presence checks.", "oneOf": [ { "$ref": "#/components/schemas/BenefitStringFilterConditions" }, { "type": "null" } ] }, "status": { "description": "Filter by benefit status.\nAllowed conditions: `$is`, `$is_not`, `$in`, `$not_in`. Allowed values: `ACTIVE`, `DRAFT`.", "oneOf": [ { "$ref": "#/components/schemas/BenefitStatusFilterConditions" }, { "type": "null" } ] }, "type": { "description": "Filter by benefit type.\nAllowed conditions: `$is`, `$is_not`, `$in`, `$not_in`. Allowed values: `POINTS`,\n`POINTS_PROPORTIONAL`, `MATERIAL`, `DIGITAL`.", "oneOf": [ { "$ref": "#/components/schemas/BenefitTypeFilterConditions" }, { "type": "null" } ] }, "created_at": { "description": "Filter by creation date.\nAllowed conditions: `$before`, `$after` (ISO 8601 date-time strings), `$is`,\n`$more_than`, `$less_than` (non-negative integers, number of days), `$has_value`,\n`$is_unknown` (presence checks).", "oneOf": [ { "$ref": "#/components/schemas/BenefitDateFilterConditions" }, { "type": "null" } ] } }, "additionalProperties": false }, "BenefitActivityListFilters": { "type": "object", "description": "Filters for the benefit activities list. Each field accepts a `conditions` object with\nat least one condition. Conditions of multiple fields are combined with the `junction`.", "properties": { "junction": { "description": "How conditions of multiple fields are combined. Defaults to `AND`.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by activity ID.\nAllowed conditions: `$is`, `$is_not`, `$in`, `$not_in`. Values must match `^laben_[a-f0-9]+$`.\n`$is`/`$is_not` accept a single value (string or 1-element array); `$in`/`$not_in`\naccept up to 100 values.", "oneOf": [ { "$ref": "#/components/schemas/BenefitActivityIdFilterConditions" }, { "type": "null" } ] }, "type": { "description": "Filter by activity type.\nAllowed conditions: `$is`, `$is_not`, `$in`, `$not_in`. Allowed values:\n`vl.benefit.created`, `vl.benefit.updated`, `vl.benefit.deleted`,\n`vl.benefit.activated`, `vl.benefit.drafted`.", "oneOf": [ { "$ref": "#/components/schemas/BenefitActivityTypeFilterConditions" }, { "type": "null" } ] }, "created_at": { "description": "Filter by activity creation date.\nAllowed conditions: `$before`, `$after` (ISO 8601 date-time strings), `$is`,\n`$more_than`, `$less_than` (non-negative integers, number of days), `$has_value`,\n`$is_unknown` (presence checks).", "oneOf": [ { "$ref": "#/components/schemas/BenefitDateFilterConditions" }, { "type": "null" } ] } }, "additionalProperties": false }, "BenefitIdFilterConditions": { "type": "object", "description": "ID filter conditions for benefit IDs. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches the exact benefit ID. Single value.", "oneOf": [ { "type": "string", "pattern": "^lben_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^lben_[a-f0-9]+$" } }, { "type": "null" } ] }, "$is_not": { "description": "Excludes the exact benefit ID. Single value.", "oneOf": [ { "type": "string", "pattern": "^lben_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^lben_[a-f0-9]+$" } }, { "type": "null" } ] }, "$in": { "description": "Matches any of the given benefit IDs. Up to 100 values.", "oneOf": [ { "type": "string", "pattern": "^lben_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^lben_[a-f0-9]+$" } }, { "type": "null" } ] }, "$not_in": { "description": "Excludes all of the given benefit IDs. Up to 100 values.", "oneOf": [ { "type": "string", "pattern": "^lben_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^lben_[a-f0-9]+$" } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "BenefitActivityIdFilterConditions": { "type": "object", "description": "ID filter conditions for benefit activity IDs. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches the exact activity ID. Single value.", "oneOf": [ { "type": "string", "pattern": "^laben_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^laben_[a-f0-9]+$" } }, { "type": "null" } ] }, "$is_not": { "description": "Excludes the exact activity ID. Single value.", "oneOf": [ { "type": "string", "pattern": "^laben_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^laben_[a-f0-9]+$" } }, { "type": "null" } ] }, "$in": { "description": "Matches any of the given activity IDs. Up to 100 values.", "oneOf": [ { "type": "string", "pattern": "^laben_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^laben_[a-f0-9]+$" } }, { "type": "null" } ] }, "$not_in": { "description": "Excludes all of the given activity IDs. Up to 100 values.", "oneOf": [ { "type": "string", "pattern": "^laben_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^laben_[a-f0-9]+$" } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "BenefitStringFilterConditions": { "type": "object", "description": "String filter conditions. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches the exact value. Single value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$is_not": { "description": "Excludes the exact value. Single value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$contains": { "description": "Matches values containing the given substring. Single value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$not_contain": { "description": "Excludes values containing the given substring. Single value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$starts_with": { "description": "Matches values starting with the given prefix. Single value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$ends_with": { "description": "Matches values ending with the given suffix. Single value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$in": { "description": "Matches any of the given values. Up to 10 values.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string" } }, { "type": "null" } ] }, "$not_in": { "description": "Excludes all of the given values. Up to 10 values.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string" } }, { "type": "null" } ] }, "$has_value": { "description": "Matches records where the field has a value. The condition value itself is ignored.", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] }, "$is_unknown": { "description": "Matches records where the field has no value. The condition value itself is ignored.", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "BenefitStatusFilterConditions": { "type": "object", "description": "Enum filter conditions for benefit status. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches the exact status. Single value.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] } }, { "type": "null" } ] }, "$is_not": { "description": "Excludes the exact status. Single value.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] } }, { "type": "null" } ] }, "$in": { "description": "Matches any of the given statuses. Up to 10 values.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] } }, { "type": "null" } ] }, "$not_in": { "description": "Excludes all of the given statuses. Up to 10 values.", "oneOf": [ { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "ACTIVE", "DRAFT" ] } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "BenefitTypeFilterConditions": { "type": "object", "description": "Enum filter conditions for benefit type. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches the exact type. Single value.", "oneOf": [ { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "MATERIAL", "DIGITAL" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "MATERIAL", "DIGITAL" ] } }, { "type": "null" } ] }, "$is_not": { "description": "Excludes the exact type. Single value.", "oneOf": [ { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "MATERIAL", "DIGITAL" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "MATERIAL", "DIGITAL" ] } }, { "type": "null" } ] }, "$in": { "description": "Matches any of the given types. Up to 10 values.", "oneOf": [ { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "MATERIAL", "DIGITAL" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "MATERIAL", "DIGITAL" ] } }, { "type": "null" } ] }, "$not_in": { "description": "Excludes all of the given types. Up to 10 values.", "oneOf": [ { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "MATERIAL", "DIGITAL" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "MATERIAL", "DIGITAL" ] } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "BenefitActivityTypeFilterConditions": { "type": "object", "description": "Enum filter conditions for benefit activity type. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches the exact activity type. Single value.", "oneOf": [ { "type": "string", "enum": [ "vl.benefit.created", "vl.benefit.updated", "vl.benefit.deleted", "vl.benefit.activated", "vl.benefit.drafted" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "vl.benefit.created", "vl.benefit.updated", "vl.benefit.deleted", "vl.benefit.activated", "vl.benefit.drafted" ] } }, { "type": "null" } ] }, "$is_not": { "description": "Excludes the exact activity type. Single value.", "oneOf": [ { "type": "string", "enum": [ "vl.benefit.created", "vl.benefit.updated", "vl.benefit.deleted", "vl.benefit.activated", "vl.benefit.drafted" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "vl.benefit.created", "vl.benefit.updated", "vl.benefit.deleted", "vl.benefit.activated", "vl.benefit.drafted" ] } }, { "type": "null" } ] }, "$in": { "description": "Matches any of the given activity types. Up to 10 values.", "oneOf": [ { "type": "string", "enum": [ "vl.benefit.created", "vl.benefit.updated", "vl.benefit.deleted", "vl.benefit.activated", "vl.benefit.drafted" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "vl.benefit.created", "vl.benefit.updated", "vl.benefit.deleted", "vl.benefit.activated", "vl.benefit.drafted" ] } }, { "type": "null" } ] }, "$not_in": { "description": "Excludes all of the given activity types. Up to 10 values.", "oneOf": [ { "type": "string", "enum": [ "vl.benefit.created", "vl.benefit.updated", "vl.benefit.deleted", "vl.benefit.activated", "vl.benefit.drafted" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "vl.benefit.created", "vl.benefit.updated", "vl.benefit.deleted", "vl.benefit.activated", "vl.benefit.drafted" ] } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "BenefitDateFilterConditions": { "type": "object", "description": "Date filter conditions. At least one condition is required.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$before": { "description": "Matches records created before the given date. ISO 8601 date-time string, single value.", "oneOf": [ { "type": "string", "format": "date-time" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "format": "date-time" } }, { "type": "null" } ] }, "$after": { "description": "Matches records created after the given date. ISO 8601 date-time string, single value.", "oneOf": [ { "type": "string", "format": "date-time" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "format": "date-time" } }, { "type": "null" } ] }, "$is": { "description": "Matches records created exactly the given number of days ago. Non-negative integer, single value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$more_than": { "description": "Matches records created more than the given number of days ago. Non-negative integer, single value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$less_than": { "description": "Matches records created less than the given number of days ago. Non-negative integer, single value.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$has_value": { "description": "Matches records where the field has a value. The condition value itself is ignored.", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] }, "$is_unknown": { "description": "Matches records where the field has no value. The condition value itself is ignored.", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "RewardCreateRequest": { "type": "object", "description": "Request body for creating a reward.\nWhen `type` is `MATERIAL`, `material` is required and\n`digital` must be null; when `type` is `DIGITAL`, `digital` is required and\n`material` must be null.", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Display name of the reward." }, "type": { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ], "description": "Reward type. MATERIAL rewards deliver a product or SKU; DIGITAL rewards deliver discount coupons, gift vouchers or loyalty card points." }, "status": { "type": "string", "enum": [ "DRAFT", "ACTIVE" ], "description": "Initial status of the reward. Defaults to DRAFT behavior when omitted." }, "validity_hours": { "description": "Hours during which the reward can be purchased. Defaults to `{ \"type\": \"ANY_TIME\" }` when omitted or null.", "oneOf": [ { "$ref": "#/components/schemas/RewardValidityHoursRequest" }, { "type": "null" } ] }, "start_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date from which the reward is available. Must be an ISO-8601 compliant date." }, "end_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date until which the reward is available. Must be an ISO-8601 compliant date." }, "material": { "description": "Material reward definition. Required when `type` is MATERIAL; must be null when `type` is DIGITAL.", "oneOf": [ { "$ref": "#/components/schemas/RewardMaterialRequest" }, { "type": "null" } ] }, "digital": { "description": "Digital reward definition. Required when `type` is DIGITAL; must be null when `type` is MATERIAL.", "oneOf": [ { "$ref": "#/components/schemas/RewardDigitalRequest" }, { "type": "null" } ] }, "costs": { "type": "array", "minItems": 1, "maxItems": 10, "description": "Point costs of the reward. Each cost defines the points to spend on a specific card definition, optionally guarded by rules.", "items": { "$ref": "#/components/schemas/RewardCostCreateRequest" } }, "refunds": { "description": "Refund policy for the reward. Defaults to `{ \"type\": \"NONE\" }` when omitted.", "oneOf": [ { "$ref": "#/components/schemas/RewardRefundsRequest" }, { "type": "null" } ] }, "metadata": { "type": [ "object", "null" ], "description": "Arbitrary key-value metadata attached to the reward, as a free-form object." } }, "required": [ "name", "type", "costs" ], "additionalProperties": false }, "RewardUpdateRequest": { "type": "object", "description": "Request body for updating a reward.\nAll properties are optional. When `type` is provided as\n`MATERIAL`, `material` is required and `digital` must be null; when `type` is\nprovided as `DIGITAL`, `digital` is required and `material` must be null.\nIn ACTIVE/INACTIVE status only `name`, `metadata`, `refunds`, `validity_hours`,\n`start_date`, `end_date` and `costs` can be updated.", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Display name of the reward." }, "type": { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ], "description": "Reward type. Can only be changed while the reward is in DRAFT status." }, "validity_hours": { "description": "Hours during which the reward can be purchased.", "oneOf": [ { "$ref": "#/components/schemas/RewardValidityHoursRequest" }, { "type": "null" } ] }, "start_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date from which the reward is available. Must be an ISO-8601 compliant date." }, "end_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date until which the reward is available. Must be an ISO-8601 compliant date." }, "material": { "description": "Material reward definition. Required when `type` is provided as MATERIAL.", "oneOf": [ { "$ref": "#/components/schemas/RewardMaterialRequest" }, { "type": "null" } ] }, "digital": { "description": "Digital reward definition. Required when `type` is provided as DIGITAL.", "oneOf": [ { "$ref": "#/components/schemas/RewardDigitalRequest" }, { "type": "null" } ] }, "refunds": { "description": "Refund policy for the reward.", "oneOf": [ { "$ref": "#/components/schemas/RewardRefundsRequest" }, { "type": "null" } ] }, "costs": { "type": "array", "minItems": 1, "maxItems": 10, "description": "Point costs of the reward. Include the `id` of an existing cost to update it; omit `id` to create a new cost.", "items": { "$ref": "#/components/schemas/RewardCostUpdateRequest" } }, "metadata": { "type": [ "object", "null" ], "description": "Arbitrary key-value metadata attached to the reward, as a free-form object." } }, "additionalProperties": false }, "RewardMaterialRequest": { "type": "object", "description": "Material reward definition.\n`type` is required. When `type` is `PRODUCT`, `product` is required and `sku` must\nbe null; when `type` is `SKU`, `sku` is required and `product` must be null.", "properties": { "type": { "type": "string", "enum": [ "PRODUCT", "SKU" ], "description": "Kind of material reward." }, "product": { "description": "Product delivered by the reward. Required when `type` is PRODUCT; must be null when `type` is SKU.", "oneOf": [ { "$ref": "#/components/schemas/RewardMaterialProductRequest" }, { "type": "null" } ] }, "sku": { "description": "SKU delivered by the reward. Required when `type` is SKU; must be null when `type` is PRODUCT.", "oneOf": [ { "$ref": "#/components/schemas/RewardMaterialSKURequest" }, { "type": "null" } ] } }, "required": [ "type" ], "additionalProperties": false }, "RewardMaterialProductRequest": { "type": "object", "description": "Product reference for a material reward.", "properties": { "id": { "type": "string", "pattern": "^prod_[a-f0-9]+", "description": "Product identifier, prefixed with `prod_`." } }, "required": [ "id" ], "additionalProperties": false }, "RewardMaterialSKURequest": { "type": "object", "description": "SKU reference for a material reward.", "properties": { "product_id": { "type": "string", "pattern": "^prod_[a-f0-9]+", "description": "Identifier of the product the SKU belongs to, prefixed with `prod_`." }, "id": { "type": "string", "pattern": "^sku_[a-f0-9]+", "description": "SKU identifier, prefixed with `sku_`." } }, "required": [ "product_id", "id" ], "additionalProperties": false }, "RewardDigitalRequest": { "type": "object", "description": "Digital reward definition. `type` is\nrequired. Exactly the object matching `type` is required and the other two must be\nnull: `DISCOUNT_COUPONS` requires `discount_coupons`, `GIFT_VOUCHERS` requires\n`gift_vouchers`, `LOYALTY_CARD_POINTS` requires `loyalty_card_points`.", "properties": { "type": { "type": "string", "enum": [ "DISCOUNT_COUPONS", "GIFT_VOUCHERS", "LOYALTY_CARD_POINTS" ], "description": "Kind of digital reward." }, "discount_coupons": { "description": "Discount coupons configuration. Required when `type` is DISCOUNT_COUPONS; must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/RewardDigitalDiscountCouponsRequest" }, { "type": "null" } ] }, "gift_vouchers": { "description": "Gift vouchers configuration. Required when `type` is GIFT_VOUCHERS; must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/RewardDigitalGiftVouchersRequest" }, { "type": "null" } ] }, "loyalty_card_points": { "description": "Loyalty card points configuration. Required when `type` is LOYALTY_CARD_POINTS; must be null otherwise.", "oneOf": [ { "$ref": "#/components/schemas/RewardDigitalLoyaltyCardPointsRequest" }, { "type": "null" } ] } }, "required": [ "type" ], "additionalProperties": false }, "RewardDigitalDiscountCouponsRequest": { "type": "object", "description": "Discount coupons digital reward configuration.", "properties": { "campaign_id": { "type": "string", "pattern": "^camp_[a-zA-Z0-9]+", "description": "Identifier of the discount coupons campaign to publish a coupon from, prefixed with `camp_`." } }, "required": [ "campaign_id" ], "additionalProperties": false }, "RewardDigitalGiftVouchersRequest": { "type": "object", "description": "Gift vouchers digital reward configuration.", "properties": { "campaign_id": { "type": "string", "pattern": "^camp_[a-zA-Z0-9]+", "description": "Identifier of the gift vouchers campaign to publish a voucher from, prefixed with `camp_`." }, "balance": { "type": "number", "minimum": 0, "description": "Gift card balance credited when the reward is delivered." } }, "required": [ "campaign_id", "balance" ], "additionalProperties": false }, "RewardDigitalLoyaltyCardPointsRequest": { "type": "object", "description": "Loyalty card points digital reward configuration.", "properties": { "points": { "type": "integer", "minimum": 1, "maximum": 9007199254740991, "description": "Number of points credited to the member's card when the reward is delivered." }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "Identifier of the card definition to credit points to, prefixed with `lcdef_`." } }, "required": [ "points", "card_definition_id" ], "additionalProperties": false }, "RewardRefundsRequest": { "type": "object", "description": "Refund policy for the reward.", "properties": { "type": { "type": "string", "enum": [ "NONE", "REFUNDABLE" ], "description": "Whether reward purchases can be refunded." } }, "required": [ "type" ], "additionalProperties": false }, "RewardValidityHoursRequest": { "type": "object", "description": "Validity hours definition. `type` is\nrequired. When `type` is `ANY_TIME`, `daily` must be null; when `type` is `DAILY`,\n`daily` is required and must contain at least one entry.", "properties": { "type": { "type": "string", "enum": [ "DAILY", "ANY_TIME" ], "description": "Whether the reward is purchasable at any time or only during specific daily windows." }, "daily": { "description": "Daily time windows. Required when `type` is DAILY; must be null when `type` is ANY_TIME.", "oneOf": [ { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/RewardValidityDailyHoursRequest" } }, { "type": "null" } ] } }, "required": [ "type" ], "additionalProperties": false }, "RewardValidityDailyHoursRequest": { "type": "object", "description": "A single daily validity window.", "properties": { "days_of_week": { "type": "array", "minItems": 1, "maxItems": 7, "description": "Days of the week the window applies to, as integers 0-6 (0 = Sunday). Values must be unique.", "items": { "type": "integer", "minimum": 0, "maximum": 6 } }, "start_time": { "type": "string", "description": "Window start time in `HH:mm` format.", "example": "09:00" }, "end_time": { "type": "string", "description": "Window end time in `HH:mm` format.", "example": "17:00" } }, "required": [ "days_of_week", "start_time", "end_time" ], "additionalProperties": false }, "RewardCostCreateRequest": { "type": "object", "description": "A reward cost for creation. `spending`\nis required. `rules`, when provided, must have between 1 and 10 properties (in\naddition to the constraints of the rules object itself).", "properties": { "rules": { "$ref": "#/components/schemas/RewardCostRulesRequest", "description": "Rules guarding this cost. Only members matching the rules can purchase the reward at this cost. Must have between 1 and 10 properties." }, "spending": { "type": "array", "minItems": 1, "maxItems": 1, "description": "Points to spend on a specific card definition. Exactly one entry is allowed.", "items": { "$ref": "#/components/schemas/RewardCostSpendingRequest" } } }, "required": [ "spending" ], "additionalProperties": false }, "RewardCostUpdateRequest": { "type": "object", "description": "A reward cost for update. Same as the\ncreate variant plus an optional `id` referencing an existing cost.", "properties": { "id": { "type": "string", "pattern": "^lrcst_[a-f0-9]+$", "description": "Identifier of an existing cost to update, prefixed with `lrcst_`. Omit to create a new cost." }, "rules": { "$ref": "#/components/schemas/RewardCostRulesRequest", "description": "Rules guarding this cost. Must have between 1 and 10 properties." }, "spending": { "type": "array", "minItems": 1, "maxItems": 1, "description": "Points to spend on a specific card definition. Exactly one entry is allowed.", "items": { "$ref": "#/components/schemas/RewardCostSpendingRequest" } } }, "required": [ "spending" ], "additionalProperties": false }, "RewardCostSpendingRequest": { "type": "object", "description": "Points spending definition for a cost.", "properties": { "points": { "type": "integer", "minimum": 1, "maximum": 9007199254740991, "description": "Number of points the member must spend." }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "Identifier of the card definition the points are spent from, prefixed with `lcdef_`." } }, "required": [ "points", "card_definition_id" ], "additionalProperties": false }, "RewardCostRulesRequest": { "type": "object", "description": "Rules group for a reward cost. Contains a required `logic` property plus numbered\nrule definitions. Every property other than `logic` must be a positive-integer\nkey (`^[1-9]\\d*$`) mapping to a rule definition. At least one rule definition is\nrequired. No other properties are allowed.", "properties": { "logic": { "type": "string", "description": "A logical formula referencing the numbered rule definitions, e.g. `\"1 AND 2\"`." } }, "patternProperties": { "^[1-9]\\d*$": { "$ref": "#/components/schemas/RewardCostRuleDefinitionRequest" } }, "required": [ "logic" ], "minProperties": 2, "additionalProperties": false }, "RewardCostRuleDefinitionRequest": { "type": "object", "description": "A single rule definition inside a cost rules group.\n`conditions`, when provided, must have between\n1 and 10 properties (one per operator). `rules` allows nesting of rule groups.", "properties": { "name": { "type": "string", "enum": [ "customer.segment", "customer.metadata", "member.metadata" ], "description": "Rule kind. `customer.segment` checks segment membership, `customer.metadata` checks a customer metadata property, `member.metadata` checks a member metadata property." }, "property": { "type": [ "string", "null" ], "description": "Metadata property name the rule applies to (for metadata rules)." }, "error": { "description": "Custom error returned when the rule is not satisfied.", "oneOf": [ { "$ref": "#/components/schemas/RewardCostRuleErrorRequest" }, { "type": "null" } ] }, "rules": { "description": "Nested rules group.", "oneOf": [ { "$ref": "#/components/schemas/RewardCostRulesRequest" }, { "type": "null" } ] }, "conditions": { "$ref": "#/components/schemas/RewardCostRuleConditionsRequest", "description": "Operator conditions for the rule. Must have between 1 and 10 properties." } }, "additionalProperties": false }, "RewardCostRuleConditionsRequest": { "type": "object", "description": "Operator conditions for a rule.\nKeys must be one of the supported operators; each value is a non-empty array of\ncondition values (objects referencing other resources, strings, integers or\nbooleans). Between 1 and 10 operator properties are allowed.", "patternProperties": { "^(\\$is|\\$is_not|\\$in|\\$not_in|\\$less_than|\\$less_than_or_equal|\\$more_than|\\$more_than_or_equal|\\$dow|\\$from)$": { "type": "array", "minItems": 1, "description": "Condition values compared using the operator given by the property name.", "items": { "oneOf": [ { "$ref": "#/components/schemas/RewardCostRuleConditionObjectRequest" }, { "type": "string" }, { "type": "integer" }, { "type": "boolean" } ] } } }, "minProperties": 1, "maxProperties": 10, "additionalProperties": false }, "RewardCostRuleConditionObjectRequest": { "type": "object", "description": "Condition value referencing another resource, e.g. a customer segment.", "properties": { "id": { "type": "string", "description": "Identifier of the referenced resource." }, "object": { "type": "string", "description": "Type of the referenced resource, e.g. `segment`." }, "source_id": { "type": [ "string", "null" ], "description": "Source identifier of the referenced resource." }, "type": { "type": [ "string", "null" ], "description": "Subtype of the referenced resource." } }, "additionalProperties": false }, "RewardCostRuleErrorRequest": { "type": "object", "description": "Custom rule error definition.", "properties": { "message": { "type": "string", "minLength": 1, "maxLength": 200, "description": "Error message returned when the rule is not satisfied." } }, "required": [ "message" ], "additionalProperties": false }, "RewardListFilters": { "type": "object", "description": "Filters for the rewards list. Each field accepts an object with a required\n`conditions` property. Conditions that are not supported for a given field type\nare rejected.", "properties": { "junction": { "description": "How multiple field filters are combined. Defaults to AND behavior.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by reward ID (ID field type). Values must match `^lrew_[a-f0-9]+$`.", "oneOf": [ { "$ref": "#/components/schemas/RewardIdFilter" }, { "type": "null" } ] }, "name": { "description": "Filter by reward name (string field type).", "oneOf": [ { "$ref": "#/components/schemas/RewardStringFilter" }, { "type": "null" } ] }, "type": { "description": "Filter by reward type (enum field type with values MATERIAL, DIGITAL).", "oneOf": [ { "$ref": "#/components/schemas/RewardTypeFilter" }, { "type": "null" } ] }, "created_at": { "description": "Filter by creation date (date field type).", "oneOf": [ { "$ref": "#/components/schemas/RewardDateFilter" }, { "type": "null" } ] } }, "additionalProperties": false }, "RewardActivityListFilters": { "type": "object", "description": "Filters for the reward activities list. Each field accepts an object with a\nrequired `conditions` property.", "properties": { "junction": { "description": "How multiple field filters are combined. Defaults to AND behavior.", "oneOf": [ { "type": "string", "enum": [ "AND", "OR" ] }, { "type": "null" } ] }, "id": { "description": "Filter by activity ID (ID field type). Values must match `^larew_[a-f0-9]+$`.", "oneOf": [ { "$ref": "#/components/schemas/RewardActivityIdFilter" }, { "type": "null" } ] }, "type": { "description": "Filter by activity type (enum field type).", "oneOf": [ { "$ref": "#/components/schemas/RewardActivityTypeFilter" }, { "type": "null" } ] }, "created_at": { "description": "Filter by activity creation date (date field type).", "oneOf": [ { "$ref": "#/components/schemas/RewardDateFilter" }, { "type": "null" } ] } }, "additionalProperties": false }, "RewardIdFilter": { "type": "object", "description": "ID filter conditions. `$is`/`$is_not` accept a single value (string or 1-element\narray); `$in`/`$not_in` accept a string or an array of 1-100 values. All values\nmust match the reward ID pattern `^lrew_[a-f0-9]+$`.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches the exact reward ID. Single value (string or 1-element array).", "oneOf": [ { "type": "string", "pattern": "^lrew_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" } }, { "type": "null" } ] }, "$is_not": { "description": "Excludes the exact reward ID. Single value (string or 1-element array).", "oneOf": [ { "type": "string", "pattern": "^lrew_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" } }, { "type": "null" } ] }, "$in": { "description": "Matches any of the given reward IDs (up to 100).", "oneOf": [ { "type": "string", "pattern": "^lrew_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" } }, { "type": "null" } ] }, "$not_in": { "description": "Excludes all of the given reward IDs (up to 100).", "oneOf": [ { "type": "string", "pattern": "^lrew_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^lrew_[a-f0-9]+$" } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "RewardActivityIdFilter": { "type": "object", "description": "ID filter conditions for reward activities. `$is`/`$is_not` accept a single value\n(string or 1-element array); `$in`/`$not_in` accept a string or an array of 1-100\nvalues. All values must match the activity ID pattern `^larew_[a-f0-9]+$`.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches the exact activity ID. Single value (string or 1-element array).", "oneOf": [ { "type": "string", "pattern": "^larew_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^larew_[a-f0-9]+$" } }, { "type": "null" } ] }, "$is_not": { "description": "Excludes the exact activity ID. Single value (string or 1-element array).", "oneOf": [ { "type": "string", "pattern": "^larew_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "pattern": "^larew_[a-f0-9]+$" } }, { "type": "null" } ] }, "$in": { "description": "Matches any of the given activity IDs (up to 100).", "oneOf": [ { "type": "string", "pattern": "^larew_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^larew_[a-f0-9]+$" } }, { "type": "null" } ] }, "$not_in": { "description": "Excludes all of the given activity IDs (up to 100).", "oneOf": [ { "type": "string", "pattern": "^larew_[a-f0-9]+$" }, { "type": "array", "minItems": 1, "maxItems": 100, "items": { "type": "string", "pattern": "^larew_[a-f0-9]+$" } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "RewardStringFilter": { "type": "object", "description": "String filter conditions. `$is`, `$is_not`, `$contains`, `$not_contain`,\n`$starts_with` and `$ends_with` accept a single value (string or 1-element array);\n`$in`/`$not_in` accept a string or an array of 1-10 values; `$has_value` and\n`$is_unknown` take no meaningful value (string or array with at most 1 item).", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Exact match. Single value (string or 1-element array).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$is_not": { "description": "Exact mismatch. Single value (string or 1-element array).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$contains": { "description": "Value contains the given substring. Single value (string or 1-element array).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$not_contain": { "description": "Value does not contain the given substring. Single value (string or 1-element array).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$starts_with": { "description": "Value starts with the given prefix. Single value (string or 1-element array).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$ends_with": { "description": "Value ends with the given suffix. Single value (string or 1-element array).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$in": { "description": "Value equals any of the given strings (up to 10).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string" } }, { "type": "null" } ] }, "$not_in": { "description": "Value equals none of the given strings (up to 10).", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string" } }, { "type": "null" } ] }, "$has_value": { "description": "Field has a value. The condition value itself is ignored (string or array with at most 1 item).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] }, "$is_unknown": { "description": "Field has no value. The condition value itself is ignored (string or array with at most 1 item).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "RewardTypeFilter": { "type": "object", "description": "Enum filter conditions for the reward `type` field. Allowed values are MATERIAL\nand DIGITAL. `$is`/`$is_not` accept a single value (string or 1-element array);\n`$in`/`$not_in` accept a string or an array of 1-10 values.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches the exact type.", "oneOf": [ { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ] } }, { "type": "null" } ] }, "$is_not": { "description": "Excludes the exact type.", "oneOf": [ { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ] }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ] } }, { "type": "null" } ] }, "$in": { "description": "Matches any of the given types.", "oneOf": [ { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ] } }, { "type": "null" } ] }, "$not_in": { "description": "Excludes all of the given types.", "oneOf": [ { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ] }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ] } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "RewardActivityTypeFilter": { "type": "object", "description": "Enum filter conditions for the activity `type` field. `$is`/`$is_not` accept a\nsingle value (string or 1-element array); `$in`/`$not_in` accept a string or an\narray of 1-10 values.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$is": { "description": "Matches the exact activity type.", "oneOf": [ { "$ref": "#/components/schemas/RewardActivityType" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "$ref": "#/components/schemas/RewardActivityType" } }, { "type": "null" } ] }, "$is_not": { "description": "Excludes the exact activity type.", "oneOf": [ { "$ref": "#/components/schemas/RewardActivityType" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "$ref": "#/components/schemas/RewardActivityType" } }, { "type": "null" } ] }, "$in": { "description": "Matches any of the given activity types (up to 10).", "oneOf": [ { "$ref": "#/components/schemas/RewardActivityType" }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "$ref": "#/components/schemas/RewardActivityType" } }, { "type": "null" } ] }, "$not_in": { "description": "Excludes all of the given activity types (up to 10).", "oneOf": [ { "$ref": "#/components/schemas/RewardActivityType" }, { "type": "array", "minItems": 1, "maxItems": 10, "items": { "$ref": "#/components/schemas/RewardActivityType" } }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "RewardDateFilter": { "type": "object", "description": "Date filter conditions. `$before`/`$after` accept an ISO-8601 date string (or a\n1-element array of one); `$is`, `$more_than` and `$less_than` accept a\nnon-negative integer value passed as a string;\n`$has_value` and `$is_unknown` take no meaningful value.", "properties": { "conditions": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "$before": { "description": "Date is before the given ISO-8601 date.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$after": { "description": "Date is after the given ISO-8601 date.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$is": { "description": "A non-negative integer value, passed as a string.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$more_than": { "description": "A non-negative integer value, passed as a string.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$less_than": { "description": "A non-negative integer value, passed as a string.", "oneOf": [ { "type": "string" }, { "type": "array", "minItems": 1, "maxItems": 1, "items": { "type": "string" } }, { "type": "null" } ] }, "$has_value": { "description": "Field has a value. The condition value itself is ignored (string or array with at most 1 item).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] }, "$is_unknown": { "description": "Field has no value. The condition value itself is ignored (string or array with at most 1 item).", "oneOf": [ { "type": "string" }, { "type": "array", "maxItems": 1 }, { "type": "null" } ] } } } }, "required": [ "conditions" ], "additionalProperties": false }, "RewardResponse": { "type": "object", "description": "A reward, as returned by the API.", "properties": { "id": { "type": "string", "pattern": "^lrew_[a-f0-9]+$", "description": "Unique reward identifier, prefixed with `lrew_`." }, "name": { "type": "string", "description": "Display name of the reward." }, "type": { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ], "description": "Reward type." }, "status": { "type": "string", "enum": [ "ACTIVE", "DRAFT", "INACTIVE", "DELETED" ], "description": "Current lifecycle status of the reward." }, "start_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date from which the reward is available, or null when not set." }, "end_date": { "type": [ "string", "null" ], "format": "date-time", "description": "Date until which the reward is available, or null when not set." }, "validity_hours": { "$ref": "#/components/schemas/RewardValidityHoursResponse", "description": "Hours during which the reward can be purchased. Always present; defaults to `{ \"type\": \"ANY_TIME\" }`." }, "material": { "$ref": "#/components/schemas/RewardMaterialResponse", "description": "Material reward definition. Present only when `type` is MATERIAL; omitted otherwise." }, "digital": { "$ref": "#/components/schemas/RewardDigitalResponse", "description": "Digital reward definition. Present only when `type` is DIGITAL; omitted otherwise." }, "refunds": { "$ref": "#/components/schemas/RewardRefundsResponse", "description": "Refund policy. Always present; defaults to `{ \"type\": \"NONE\" }`." }, "costs": { "type": "array", "description": "Point costs of the reward. Empty array when no costs are defined.", "items": { "$ref": "#/components/schemas/RewardCostResponse" } }, "metadata": { "type": "object", "description": "Arbitrary key-value metadata attached to the reward. Empty object when not set." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the reward was created (ISO-8601)." }, "updated_at": { "type": [ "string", "null" ], "format": "date-time", "description": "Timestamp when the reward was last updated (ISO-8601), or null when never updated." }, "object": { "type": "string", "const": "reward", "description": "Object type marker; always `reward`." } }, "required": [ "id", "name", "type", "status", "validity_hours", "refunds", "costs", "metadata", "created_at", "object" ] }, "RewardMaterialResponse": { "type": "object", "description": "Material reward definition.", "properties": { "type": { "type": "string", "enum": [ "PRODUCT", "SKU" ], "description": "Kind of material reward." }, "product": { "$ref": "#/components/schemas/RewardMaterialProductResponse", "description": "Product delivered by the reward. Present only when `type` is PRODUCT; omitted otherwise." }, "sku": { "$ref": "#/components/schemas/RewardMaterialSKUResponse", "description": "SKU delivered by the reward. Present only when `type` is SKU; omitted otherwise." } }, "required": [ "type" ] }, "RewardMaterialProductResponse": { "type": "object", "description": "Product reference.", "properties": { "id": { "type": "string", "pattern": "^prod_[a-f0-9]+", "description": "Product identifier, prefixed with `prod_`." } }, "required": [ "id" ] }, "RewardMaterialSKUResponse": { "type": "object", "description": "SKU reference.", "properties": { "product_id": { "type": "string", "pattern": "^prod_[a-f0-9]+", "description": "Identifier of the product the SKU belongs to, prefixed with `prod_`." }, "id": { "type": "string", "pattern": "^sku_[a-f0-9]+", "description": "SKU identifier, prefixed with `sku_`." } }, "required": [ "product_id", "id" ] }, "RewardDigitalResponse": { "type": "object", "description": "Digital reward definition. Only the object matching `type` is present; the others are omitted.", "properties": { "type": { "type": "string", "enum": [ "DISCOUNT_COUPONS", "GIFT_VOUCHERS", "LOYALTY_CARD_POINTS" ], "description": "Kind of digital reward." }, "discount_coupons": { "$ref": "#/components/schemas/RewardDigitalDiscountCouponsResponse", "description": "Discount coupons configuration. Present only when `type` is DISCOUNT_COUPONS." }, "gift_vouchers": { "$ref": "#/components/schemas/RewardDigitalGiftVouchersResponse", "description": "Gift vouchers configuration. Present only when `type` is GIFT_VOUCHERS." }, "loyalty_card_points": { "$ref": "#/components/schemas/RewardDigitalLoyaltyCardPointsResponse", "description": "Loyalty card points configuration. Present only when `type` is LOYALTY_CARD_POINTS." } }, "required": [ "type" ] }, "RewardDigitalDiscountCouponsResponse": { "type": "object", "description": "Discount coupons configuration.", "properties": { "campaign_id": { "type": "string", "pattern": "^camp_[a-zA-Z0-9]+", "description": "Identifier of the discount coupons campaign, prefixed with `camp_`." } }, "required": [ "campaign_id" ] }, "RewardDigitalGiftVouchersResponse": { "type": "object", "description": "Gift vouchers configuration.", "properties": { "campaign_id": { "type": "string", "pattern": "^camp_[a-zA-Z0-9]+", "description": "Identifier of the gift vouchers campaign, prefixed with `camp_`." }, "balance": { "type": "number", "description": "Gift card balance credited when the reward is delivered." } }, "required": [ "campaign_id", "balance" ] }, "RewardDigitalLoyaltyCardPointsResponse": { "type": "object", "description": "Loyalty card points configuration.", "properties": { "points": { "type": "integer", "description": "Number of points credited when the reward is delivered." }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "Identifier of the card definition points are credited to, prefixed with `lcdef_`." } }, "required": [ "points", "card_definition_id" ] }, "RewardRefundsResponse": { "type": "object", "description": "Refund policy.", "properties": { "type": { "type": "string", "enum": [ "NONE", "REFUNDABLE" ], "description": "Whether reward purchases can be refunded. Defaults to NONE." } }, "required": [ "type" ] }, "RewardValidityHoursResponse": { "type": "object", "description": "Validity hours. `daily` is present only when `type` is DAILY; omitted otherwise.", "properties": { "type": { "type": "string", "enum": [ "DAILY", "ANY_TIME" ], "description": "Whether the reward is purchasable at any time or only during specific daily windows." }, "daily": { "type": "array", "description": "Daily time windows. Present only when `type` is DAILY.", "items": { "$ref": "#/components/schemas/RewardValidityDailyHoursResponse" } } }, "required": [ "type" ] }, "RewardValidityDailyHoursResponse": { "type": "object", "description": "A single daily validity window.", "properties": { "days_of_week": { "type": "array", "description": "Days of the week the window applies to, as integers 0-6 (0 = Sunday).", "items": { "type": "integer", "minimum": 0, "maximum": 6 } }, "start_time": { "type": "string", "description": "Window start time in `HH:mm` format.", "example": "09:00" }, "end_time": { "type": "string", "description": "Window end time in `HH:mm` format.", "example": "17:00" } }, "required": [ "days_of_week", "start_time", "end_time" ] }, "RewardCostResponse": { "type": "object", "description": "A reward cost. `rules` is omitted when the cost has no\nrule definitions; `spending` is null when no spending is defined.", "properties": { "id": { "type": "string", "pattern": "^lrcst_[a-f0-9]+$", "description": "Unique cost identifier, prefixed with `lrcst_`." }, "rules": { "$ref": "#/components/schemas/RewardCostRuleGroupResponse", "description": "Rules guarding this cost. Omitted when the cost has no rule definitions." }, "spending": { "type": [ "array", "null" ], "description": "Points spending definitions, or null when none are defined.", "items": { "$ref": "#/components/schemas/RewardCostSpendingResponse" } } }, "required": [ "id" ] }, "RewardCostSpendingResponse": { "type": "object", "description": "Points spending definition.", "properties": { "points": { "type": "integer", "description": "Number of points the member must spend." }, "card_definition_id": { "type": "string", "pattern": "^lcdef_[a-f0-9]+$", "description": "Identifier of the card definition the points are spent from, prefixed with `lcdef_`." } }, "required": [ "points", "card_definition_id" ] }, "RewardCostRuleGroupResponse": { "type": "object", "description": "Rules group. Contains a `logic` formula string plus\nnumbered rule definition properties (positive-integer keys).", "properties": { "logic": { "type": "string", "description": "Logical formula combining the numbered rule definitions, e.g. `\"1 AND 2\"`." } }, "patternProperties": { "^[1-9]\\d*$": { "$ref": "#/components/schemas/RewardCostRuleDefinitionResponse" } } }, "RewardCostRuleDefinitionResponse": { "type": "object", "description": "A single rule definition. `conditions`, `rules` and `error` are omitted when not set.", "properties": { "name": { "type": "string", "enum": [ "customer.segment", "customer.metadata", "member.metadata" ], "description": "Rule kind." }, "property": { "type": [ "string", "null" ], "description": "Metadata property name the rule applies to (for metadata rules)." }, "conditions": { "type": "object", "description": "Operator conditions for the rule (keys are operators such as `$is`, `$in`; values are arrays of condition values). Omitted when not set." }, "rules": { "$ref": "#/components/schemas/RewardCostRuleGroupResponse", "description": "Nested rules group. Omitted when not set." }, "error": { "type": "object", "description": "Custom rule error definition with a `message` property. Omitted when not set.", "properties": { "message": { "type": "string", "description": "Error message returned when the rule is not satisfied." } } } } }, "RewardListResponse": { "type": "object", "description": "Cursor-paginated list of rewards.", "properties": { "data": { "type": "array", "description": "The rewards on the current page.", "items": { "$ref": "#/components/schemas/RewardResponse" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/RewardListCursor" }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type marker; always `list`." } }, "required": [ "data", "cursor", "object" ] }, "RewardListCursor": { "type": "object", "description": "Pagination cursor.", "properties": { "next": { "type": "string", "description": "Cursor value to pass as the `cursor` query parameter to fetch the next page." }, "expires_at": { "type": "string", "format": "date-time", "description": "Timestamp when the cursor expires." } }, "required": [ "next" ] }, "RewardActivityType": { "type": "string", "description": "Reward activity type.", "enum": [ "vl.reward.created", "vl.reward.updated", "vl.reward.deleted", "vl.reward.assigned", "vl.reward.unassigned", "vl.reward.activated", "vl.reward.deactivated", "vl.reward.drafted" ] }, "RewardActivity": { "type": "object", "description": "A reward activity entry.", "properties": { "id": { "type": "string", "pattern": "^larew_[a-f0-9]+$", "description": "Unique activity identifier, prefixed with `larew_`." }, "type": { "$ref": "#/components/schemas/RewardActivityType", "description": "Type of the activity." }, "data": { "$ref": "#/components/schemas/RewardActivityData", "description": "Activity payload. Always contains a snapshot of the reward; assigned/unassigned activities also contain the program and the program-reward assignment." }, "created_at": { "type": "string", "format": "date-time", "description": "Timestamp when the activity occurred (ISO-8601)." }, "group_id": { "type": [ "string", "null" ], "description": "Identifier grouping related activities recorded together. Omitted or null when the activity is not part of a group." }, "source": { "$ref": "#/components/schemas/RewardActivitySource", "description": "Origin of the activity. Omitted when not recorded." }, "reward_id": { "type": "string", "pattern": "^lrew_[a-f0-9]+$", "description": "Identifier of the reward the activity belongs to, prefixed with `lrew_`." } }, "required": [ "id", "type", "data", "created_at", "reward_id" ] }, "RewardActivityData": { "type": "object", "description": "Activity payload. `reward` is always present and contains a full snapshot of the\nreward at the time of the activity. For `vl.reward.assigned` and\n`vl.reward.unassigned` activities, `program` (a snapshot of the program) and\n`program_reward` (a snapshot of the program-reward assignment) are also present.", "properties": { "reward": { "$ref": "#/components/schemas/RewardResponse", "description": "Snapshot of the reward at the time of the activity." }, "program": { "type": "object", "description": "Snapshot of the program. Present only for assigned/unassigned activities." }, "program_reward": { "type": "object", "description": "Snapshot of the program-reward assignment. Present only for assigned/unassigned activities." } }, "required": [ "reward" ] }, "RewardActivitySource": { "type": "object", "description": "Origin of an activity.", "properties": { "channel": { "type": "string", "enum": [ "USER_PORTAL", "API", "CLIENT_API", "INTERNAL" ], "description": "Channel through which the change was made." }, "user": { "$ref": "#/components/schemas/RewardActivitySourceUser", "description": "User who made the change. Omitted when not applicable." }, "api_key": { "$ref": "#/components/schemas/RewardActivitySourceApiKey", "description": "API key used to make the change. Omitted when not applicable." } }, "required": [ "channel" ] }, "RewardActivitySourceUser": { "type": "object", "description": "User reference in an activity source.", "properties": { "id": { "type": "string", "description": "User identifier." } }, "required": [ "id" ] }, "RewardActivitySourceApiKey": { "type": "object", "description": "API key reference in an activity source.", "properties": { "name": { "type": "string", "description": "Name of the API key." }, "app_id": { "type": "string", "description": "Application identifier of the API key." }, "client_app_id": { "type": "string", "description": "Client application identifier of the API key." } } }, "RewardActivityListResponse": { "type": "object", "description": "Cursor-paginated list of reward activities.", "properties": { "data": { "type": "array", "description": "The activities on the current page.", "items": { "$ref": "#/components/schemas/RewardActivity" } }, "cursor": { "description": "Pagination cursor, or null when there are no more results.", "oneOf": [ { "$ref": "#/components/schemas/RewardListCursor" }, { "type": "null" } ] }, "object": { "type": "string", "const": "list", "description": "Object type marker; always `list`." } }, "required": [ "data", "cursor", "object" ] }, "ExamineCustomerIdentification": { "type": "object", "description": "How the examined customer is identified. Depending on `type`, exactly one of `customer_id`, `customer_source_id` or `member_id` is required; the other two must not be present.", "properties": { "type": { "type": "string", "enum": [ "customer_id", "customer_source_id", "member_id" ], "description": "Identification method." }, "customer_id": { "type": [ "string", "null" ], "pattern": "^cust_[a-zA-Z0-9]+", "description": "Customer ID (`cust_...`). Required when `type` is `customer_id`." }, "customer_source_id": { "type": [ "string", "number", "null" ], "description": "Customer source ID. May be provided as a string or a number. Required when `type` is `customer_source_id`." }, "member_id": { "type": [ "string", "null" ], "pattern": "^lmbr_[a-f0-9]+$", "description": "Loyalty member ID (`lmbr_...`). Required when `type` is `member_id`." } }, "required": [ "type" ], "additionalProperties": false, "allOf": [ { "if": { "required": [ "type" ], "properties": { "type": { "const": "customer_id" } } }, "then": { "required": [ "customer_id" ], "not": { "anyOf": [ { "required": [ "customer_source_id" ] }, { "required": [ "member_id" ] } ] } } }, { "if": { "required": [ "type" ], "properties": { "type": { "const": "customer_source_id" } } }, "then": { "required": [ "customer_source_id" ], "not": { "anyOf": [ { "required": [ "customer_id" ] }, { "required": [ "member_id" ] } ] } } }, { "if": { "required": [ "type" ], "properties": { "type": { "const": "member_id" } } }, "then": { "required": [ "member_id" ], "not": { "anyOf": [ { "required": [ "customer_id" ] }, { "required": [ "customer_source_id" ] } ] } } } ] }, "ExamineEarningRulesRequest": { "type": "object", "description": "Request body for examining earning rules.\nWhen `trigger.type` is `SPECIFIC`, the context object matching the specific event is\nrequired and the other context objects must not be present:\n`customer.order.paid` -> `customer_order_paid`,\n`customer.segment.entered` -> `customer_segment_entered`,\n`customer.custom_event` -> `customer_custom_event`.", "properties": { "trigger": { "$ref": "#/components/schemas/ExamineEarningRulesTrigger" }, "customer_identification": { "$ref": "#/components/schemas/ExamineCustomerIdentification" }, "customer_order_paid": { "$ref": "#/components/schemas/ExamineEarningRulesCustomerOrderPaid" }, "customer_segment_entered": { "$ref": "#/components/schemas/ExamineEarningRulesCustomerSegmentEntered" }, "customer_custom_event": { "$ref": "#/components/schemas/ExamineEarningRulesCustomerCustomEvent" } }, "required": [ "trigger", "customer_identification" ], "additionalProperties": false, "allOf": [ { "if": { "required": [ "trigger" ], "properties": { "trigger": { "properties": { "type": { "const": "SPECIFIC" }, "specific": { "properties": { "event": { "const": "customer.order.paid" } } } } } } }, "then": { "required": [ "customer_order_paid" ], "not": { "anyOf": [ { "required": [ "customer_segment_entered" ] }, { "required": [ "customer_custom_event" ] } ] } } }, { "if": { "required": [ "trigger" ], "properties": { "trigger": { "properties": { "type": { "const": "SPECIFIC" }, "specific": { "properties": { "event": { "const": "customer.segment.entered" } } } } } } }, "then": { "required": [ "customer_segment_entered" ], "not": { "anyOf": [ { "required": [ "customer_order_paid" ] }, { "required": [ "customer_custom_event" ] } ] } } }, { "if": { "required": [ "trigger" ], "properties": { "trigger": { "properties": { "type": { "const": "SPECIFIC" }, "specific": { "properties": { "event": { "const": "customer.custom_event" } } } } } } }, "then": { "required": [ "customer_custom_event" ], "not": { "anyOf": [ { "required": [ "customer_order_paid" ] }, { "required": [ "customer_segment_entered" ] } ] } } } ] }, "ExamineEarningRulesTrigger": { "type": "object", "description": "Which trigger events to examine. With `ALL`, all trigger events are examined and `specific` must be null/absent. With `SPECIFIC`, `specific` is required.", "properties": { "type": { "type": "string", "enum": [ "ALL", "SPECIFIC" ], "description": "Trigger examination mode." }, "specific": { "description": "Specific event selection. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/ExamineEarningRulesTriggerSpecific" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "ALL" } } }, "then": { "properties": { "specific": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "SPECIFIC" } } }, "then": { "required": [ "specific" ], "properties": { "specific": { "$ref": "#/components/schemas/ExamineEarningRulesTriggerSpecific" } } } } ] }, "ExamineEarningRulesTriggerSpecific": { "type": "object", "description": "Specific trigger event to examine.", "properties": { "event": { "type": "string", "enum": [ "customer.order.paid", "customer.segment.entered", "customer.custom_event" ], "description": "Trigger event." } }, "required": [ "event" ], "additionalProperties": false }, "ExamineEarningRulesCustomer": { "type": "object", "description": "Customer metadata overrides used during examination.", "properties": { "metadata": { "description": "Customer metadata overrides. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleMetadata" }, { "type": "null" } ] } }, "additionalProperties": false }, "ExamineEarningRulesMember": { "type": "object", "description": "Member metadata overrides used during examination.", "properties": { "metadata": { "description": "Member metadata overrides. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleMetadata" }, { "type": "null" } ] } }, "additionalProperties": false }, "ExamineEarningRulesOrderItemProduct": { "type": "object", "description": "Product details for an examined order item.", "properties": { "id": { "type": [ "string", "number", "null" ], "description": "Product ID. May be provided as a string or a number. Nullable." }, "source_id": { "type": [ "string", "number", "null" ], "description": "Product source ID. May be provided as a string or a number. Nullable." }, "price": { "type": [ "string", "number", "null" ], "description": "Product price - an integer amount of at most 9007199254740991. May be provided as a string or a number. Nullable." } }, "additionalProperties": false }, "ExamineEarningRulesOrderItemSku": { "type": "object", "description": "SKU details for an examined order item.", "properties": { "id": { "type": [ "string", "number", "null" ], "description": "SKU ID. May be provided as a string or a number. Nullable." }, "source_id": { "type": [ "string", "number", "null" ], "description": "SKU source ID. May be provided as a string or a number. Nullable." }, "price": { "type": [ "string", "number", "null" ], "description": "SKU price - an integer amount of at most 9007199254740991. May be provided as a string or a number. Nullable." } }, "additionalProperties": false }, "ExamineEarningRulesOrderItem": { "type": "object", "description": "A hypothetical order line item used for estimation.", "properties": { "id": { "type": [ "string", "null" ], "description": "Order item ID. Nullable." }, "source_id": { "type": [ "string", "number", "null" ], "description": "Order item source ID. May be provided as a string or a number. Nullable." }, "product_id": { "type": [ "string", "number", "null" ], "description": "Product ID. May be provided as a string or a number. Nullable." }, "sku_id": { "type": [ "string", "number", "null" ], "description": "SKU ID. May be provided as a string or a number. Nullable." }, "related_object": { "description": "Whether the item refers to a product or a SKU. Nullable.", "oneOf": [ { "type": "string", "enum": [ "product", "sku" ] }, { "type": "null" } ] }, "amount": { "type": [ "string", "number", "null" ], "description": "Item amount before discounts - a non-negative integer. May be provided as a string or a number. Nullable." }, "discount_amount": { "type": [ "string", "number", "null" ], "description": "Item discount amount - a non-negative integer. May be provided as a string or a number. Nullable." }, "quantity": { "type": [ "string", "number", "null" ], "description": "Item quantity - a positive integer. May be provided as a string or a number. Nullable." }, "price": { "type": [ "string", "number", "null" ], "description": "Item unit price - a non-negative integer. May be provided as a string or a number. Nullable." }, "product": { "description": "Product details. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/ExamineEarningRulesOrderItemProduct" }, { "type": "null" } ] }, "sku": { "description": "SKU details. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/ExamineEarningRulesOrderItemSku" }, { "type": "null" } ] }, "metadata": { "description": "Order item metadata. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleMetadata" }, { "type": "null" } ] } }, "additionalProperties": false }, "ExamineEarningRulesOrder": { "type": "object", "description": "A hypothetical order used for estimation.", "properties": { "amount": { "type": [ "string", "number", "null" ], "description": "Order amount after discounts - a non-negative integer. May be provided as a string or a number. Nullable." }, "initial_amount": { "type": [ "string", "number", "null" ], "description": "Order amount before discounts - a non-negative integer. May be provided as a string or a number. Nullable." }, "discount_amount": { "type": [ "string", "number", "null" ], "description": "Total discount amount - a non-negative integer. May be provided as a string or a number. Nullable." }, "items": { "type": [ "array", "null" ], "maxItems": 500, "description": "Order line items (up to 500). Nullable.", "items": { "$ref": "#/components/schemas/ExamineEarningRulesOrderItem" } }, "metadata": { "description": "Order metadata. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleMetadata" }, { "type": "null" } ] } }, "additionalProperties": false }, "ExamineEarningRulesCustomerOrderPaid": { "type": "object", "description": "Context for examining `customer.order.paid` earning rules.", "properties": { "customer": { "$ref": "#/components/schemas/ExamineEarningRulesCustomer" }, "member": { "$ref": "#/components/schemas/ExamineEarningRulesMember" }, "order": { "$ref": "#/components/schemas/ExamineEarningRulesOrder" } }, "additionalProperties": false }, "ExamineEarningRulesCustomerSegmentEntered": { "type": "object", "description": "Context for examining `customer.segment.entered` earning rules.", "properties": { "customer": { "$ref": "#/components/schemas/ExamineEarningRulesCustomer" }, "member": { "$ref": "#/components/schemas/ExamineEarningRulesMember" } }, "additionalProperties": false }, "ExamineEarningRulesCustomEventSpecific": { "type": "object", "description": "A specific custom event to examine.", "properties": { "schema_id": { "type": "string", "pattern": "^ms_[a-zA-Z0-9]+", "description": "Custom event schema ID (`ms_...`)." }, "metadata": { "description": "Custom event metadata. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleMetadata" }, { "type": "null" } ] } }, "required": [ "schema_id" ], "additionalProperties": false }, "ExamineEarningRulesCustomEventAll": { "type": "object", "description": "Metadata applied when examining all custom events.", "properties": { "metadata": { "description": "Custom event metadata. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleMetadata" }, { "type": "null" } ] } }, "additionalProperties": false }, "ExamineEarningRulesCustomerCustomEventSpecific": { "type": "object", "description": "Context for examining a specific custom event.", "properties": { "customer": { "$ref": "#/components/schemas/ExamineEarningRulesCustomer" }, "member": { "$ref": "#/components/schemas/ExamineEarningRulesMember" }, "custom_event": { "$ref": "#/components/schemas/ExamineEarningRulesCustomEventSpecific" } }, "required": [ "custom_event" ], "additionalProperties": false }, "ExamineEarningRulesCustomerCustomEventAll": { "type": "object", "description": "Context for examining all custom events.", "properties": { "customer": { "$ref": "#/components/schemas/ExamineEarningRulesCustomer" }, "member": { "$ref": "#/components/schemas/ExamineEarningRulesMember" }, "custom_event": { "$ref": "#/components/schemas/ExamineEarningRulesCustomEventAll" } }, "additionalProperties": false }, "ExamineEarningRulesCustomerCustomEvent": { "type": "object", "description": "Context for examining `customer.custom_event` earning rules. With `type` = `ALL`, `all` is required and `specific` must be null/absent. With `SPECIFIC`, `specific` is required and `all` must be null/absent.", "properties": { "type": { "type": "string", "enum": [ "ALL", "SPECIFIC" ], "description": "Whether to examine all custom events or one specific event." }, "all": { "description": "Context for all custom events. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/ExamineEarningRulesCustomerCustomEventAll" }, { "type": "null" } ] }, "specific": { "description": "Context for a specific custom event. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/ExamineEarningRulesCustomerCustomEventSpecific" }, { "type": "null" } ] } }, "additionalProperties": false, "allOf": [ { "required": [ "type" ] }, { "if": { "properties": { "type": { "const": "ALL" } } }, "then": { "required": [ "all" ], "properties": { "specific": { "type": "null" } } } }, { "if": { "properties": { "type": { "const": "SPECIFIC" } } }, "then": { "required": [ "specific" ], "properties": { "all": { "type": "null" }, "specific": { "$ref": "#/components/schemas/ExamineEarningRulesCustomerCustomEventSpecific" } } } } ] }, "ExamineCustomerReference": { "type": "object", "description": "Customer reference in examine results.", "properties": { "id": { "type": "string", "description": "Customer ID (`cust_...`)." }, "source_id": { "type": "string", "description": "Customer source ID." }, "metadata": { "type": "object", "description": "Customer metadata (empty object when unset).", "additionalProperties": true }, "object": { "type": "string", "const": "customer", "description": "Object type marker. Always `customer`." } } }, "ExamineProgramReference": { "type": "object", "description": "Program reference in examine results.", "properties": { "id": { "type": "string", "description": "Program ID (`lprg_...`)." }, "name": { "type": "string", "description": "Program name." }, "metadata": { "type": "object", "description": "Program metadata (empty object when unset).", "additionalProperties": true }, "object": { "type": "string", "const": "program", "description": "Object type marker. Always `program`." } } }, "ExamineMemberReference": { "type": "object", "description": "Member reference in examine results.", "properties": { "id": { "type": "string", "description": "Member ID (`lmbr_...`)." }, "customer_id": { "type": "string", "description": "Customer ID the member belongs to." }, "program_id": { "type": "string", "description": "Program ID the member belongs to." }, "metadata": { "type": "object", "description": "Member metadata (empty object when unset).", "additionalProperties": true }, "object": { "type": "string", "const": "member", "description": "Object type marker. Always `member`." } } }, "ExamineCardReference": { "type": "object", "description": "Card reference in examine results.", "properties": { "id": { "type": "string", "description": "Card ID (`lcrd_...`)." }, "card_definition_id": { "type": "string", "description": "Card definition ID (`lcdef_...`)." }, "card_type": { "type": "string", "enum": [ "INDIVIDUAL" ], "description": "Card type. Currently only `INDIVIDUAL` exists." }, "code": { "type": [ "string", "null" ], "description": "Card code. May be null right after member creation because card codes are generated asynchronously." }, "object": { "type": "string", "const": "card", "description": "Object type marker. Always `card`." } } }, "ExamineEarningRuleReference": { "type": "object", "description": "Earning rule reference in examine results.", "properties": { "id": { "type": "string", "description": "Earning rule ID (`lern_...`)." }, "object": { "type": "string", "const": "earning_rule", "description": "Object type marker. Always `earning_rule`." } } }, "ExamineEarningRuleDetail": { "type": "object", "description": "Earning rule detail in examine results.", "properties": { "id": { "type": "string", "description": "Earning rule ID (`lern_...`)." }, "name": { "type": "string", "description": "Earning rule name." }, "metadata": { "type": "object", "description": "Earning rule metadata (empty object when unset).", "additionalProperties": true }, "object": { "type": "string", "const": "earning_rule", "description": "Object type marker. Always `earning_rule`." } } }, "ExamineBenefitReference": { "type": "object", "description": "Benefit reference in examine results.", "properties": { "id": { "type": "string", "description": "Benefit ID (`lben_...`)." }, "name": { "type": "string", "description": "Benefit name." }, "type": { "type": "string", "enum": [ "POINTS", "POINTS_PROPORTIONAL", "MATERIAL", "DIGITAL" ], "description": "Benefit type." }, "object": { "type": "string", "const": "benefit", "description": "Object type marker. Always `benefit`." } } }, "ExamineEarningRulesCardEarningRuleEstimation": { "type": "object", "description": "Points estimation from a single earning rule for a card.", "properties": { "earning_rule": { "$ref": "#/components/schemas/ExamineEarningRuleReference" }, "points_estimation": { "type": "number", "description": "Estimated points this earning rule would award to the card." }, "object": { "type": "string", "const": "earning_rule_estimation", "description": "Object type marker. Always `earning_rule_estimation`." } } }, "ExamineEarningRulesCardEstimation": { "type": "object", "description": "Points estimation for a single card.", "properties": { "card": { "$ref": "#/components/schemas/ExamineCardReference" }, "points_estimation": { "type": "number", "description": "Total estimated points for the card across matching earning rules." }, "earning_rules": { "type": "array", "description": "Per-earning-rule estimations contributing to the total.", "items": { "$ref": "#/components/schemas/ExamineEarningRulesCardEarningRuleEstimation" } }, "object": { "type": "string", "const": "card_estimation", "description": "Object type marker. Always `card_estimation`." } } }, "ExamineEarningRulesBenefitEarningRuleEstimation": { "type": "object", "description": "Earning rule granting a benefit.", "properties": { "earning_rule": { "$ref": "#/components/schemas/ExamineEarningRuleReference" }, "object": { "type": "string", "const": "earning_rule_estimation", "description": "Object type marker. Always `earning_rule_estimation`." } } }, "ExamineEarningRulesBenefitEstimation": { "type": "object", "description": "Benefit estimation.", "properties": { "benefit": { "$ref": "#/components/schemas/ExamineBenefitReference" }, "earning_rules": { "type": "array", "description": "Earning rules that would grant this benefit.", "items": { "$ref": "#/components/schemas/ExamineEarningRulesBenefitEarningRuleEstimation" } }, "object": { "type": "string", "const": "benefit_estimation", "description": "Object type marker. Always `benefit_estimation`." } } }, "ExamineEarningRulesMembership": { "type": "object", "description": "Earning opportunities for one program membership.", "properties": { "member": { "$ref": "#/components/schemas/ExamineMemberReference" }, "program": { "$ref": "#/components/schemas/ExamineProgramReference" }, "cards": { "type": "array", "description": "Points estimations per card.", "items": { "$ref": "#/components/schemas/ExamineEarningRulesCardEstimation" } }, "benefits": { "type": "array", "description": "Benefit estimations.", "items": { "$ref": "#/components/schemas/ExamineEarningRulesBenefitEstimation" } }, "object": { "type": "string", "const": "member_earnings_opportunity", "description": "Object type marker. Always `member_earnings_opportunity`." } } }, "ExamineEarningRulesResponse": { "type": "object", "description": "Earning rules examination result.", "properties": { "event": { "type": "string", "description": "Examined trigger event (e.g. `customer.order.paid`, `customer.segment.entered`, `customer.custom_event`)." }, "customer": { "$ref": "#/components/schemas/ExamineCustomerReference" }, "earning_rules": { "type": "array", "description": "All earning rules that matched during examination (deduplicated).", "items": { "$ref": "#/components/schemas/ExamineEarningRuleDetail" } }, "memberships": { "type": "array", "description": "Earning opportunities per program membership.", "items": { "$ref": "#/components/schemas/ExamineEarningRulesMembership" } }, "object": { "type": "string", "const": "earnings_examine_result", "description": "Object type marker. Always `earnings_examine_result`." } } }, "ExamineRewardsRequest": { "type": "object", "description": "Request body for examining rewards.", "properties": { "customer_identification": { "$ref": "#/components/schemas/ExamineCustomerIdentification" }, "customer": { "type": "object", "description": "Customer metadata overrides used during examination.", "additionalProperties": false, "properties": { "metadata": { "description": "Customer metadata overrides. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleMetadata" }, { "type": "null" } ] } } }, "member": { "type": "object", "description": "Member metadata overrides used during examination.", "additionalProperties": false, "properties": { "metadata": { "description": "Member metadata overrides. Nullable.", "oneOf": [ { "$ref": "#/components/schemas/EarningRuleMetadata" }, { "type": "null" } ] } } } }, "required": [ "customer_identification" ], "additionalProperties": false }, "ExamineRewardsRewardReference": { "type": "object", "description": "Reward reference.", "properties": { "id": { "type": "string", "description": "Reward ID (`lrew_...`)." }, "object": { "type": "string", "const": "reward", "description": "Object type marker. Always `reward`." } } }, "ExamineRewardsRewardDetail": { "type": "object", "description": "Reward detail.", "properties": { "id": { "type": "string", "description": "Reward ID (`lrew_...`)." }, "name": { "type": "string", "description": "Reward name." }, "type": { "type": "string", "enum": [ "MATERIAL", "DIGITAL" ], "description": "Reward type." }, "metadata": { "type": "object", "description": "Reward metadata (empty object when unset).", "additionalProperties": true }, "object": { "type": "string", "const": "reward", "description": "Object type marker. Always `reward`." } } }, "ExamineRewardsRewardCost": { "type": "object", "description": "Reward cost.", "properties": { "points": { "type": "number", "description": "Points cost of the reward for this card." }, "object": { "type": "string", "const": "reward_cost", "description": "Object type marker. Always `reward_cost`." } } }, "ExamineRewardsRewardUnavailabilityReason": { "type": "object", "description": "Reason a reward is unavailable.", "properties": { "reason": { "type": "string", "enum": [ "insufficient_balance", "out_of_stock", "no_matching_cost", "no_card_for_cost", "no_target_card", "reward_inactive" ], "description": "Unavailability reason code." }, "details": { "type": "string", "description": "Additional details. Absent when not provided." }, "object": { "type": "string", "const": "reward_unavailability_reason", "description": "Object type marker. Always `reward_unavailability_reason`." } } }, "ExamineRewardsCardRewardEstimation": { "type": "object", "description": "Reward availability estimation for a card.", "properties": { "reward": { "$ref": "#/components/schemas/ExamineRewardsRewardReference" }, "status": { "type": "string", "enum": [ "AVAILABLE", "UNAVAILABLE" ], "description": "Whether the reward can currently be obtained with this card." }, "cost": { "$ref": "#/components/schemas/ExamineRewardsRewardCost", "description": "Points cost. Absent when no cost applies." }, "unavailability_reasons": { "type": "array", "description": "Reasons the reward is unavailable. Absent when the reward is available.", "items": { "$ref": "#/components/schemas/ExamineRewardsRewardUnavailabilityReason" } }, "object": { "type": "string", "const": "reward_estimation", "description": "Object type marker. Always `reward_estimation`." } } }, "ExamineRewardsCardEstimation": { "type": "object", "description": "Reward estimations for a single card.", "properties": { "card": { "$ref": "#/components/schemas/ExamineCardReference" }, "rewards": { "type": "array", "description": "Reward availability estimations for this card.", "items": { "$ref": "#/components/schemas/ExamineRewardsCardRewardEstimation" } }, "object": { "type": "string", "const": "card_estimation", "description": "Object type marker. Always `card_estimation`." } } }, "ExamineRewardsMembership": { "type": "object", "description": "Reward opportunities for one program membership.", "properties": { "member": { "$ref": "#/components/schemas/ExamineMemberReference" }, "program": { "$ref": "#/components/schemas/ExamineProgramReference" }, "cards": { "type": "array", "description": "Reward estimations per card.", "items": { "$ref": "#/components/schemas/ExamineRewardsCardEstimation" } }, "object": { "type": "string", "const": "member_rewards_opportunity", "description": "Object type marker. Always `member_rewards_opportunity`." } } }, "ExamineRewardsResponse": { "type": "object", "description": "Rewards examination result.", "properties": { "customer": { "$ref": "#/components/schemas/ExamineCustomerReference" }, "rewards": { "type": "array", "description": "All rewards considered during examination (deduplicated).", "items": { "$ref": "#/components/schemas/ExamineRewardsRewardDetail" } }, "memberships": { "type": "array", "description": "Reward opportunities per program membership.", "items": { "$ref": "#/components/schemas/ExamineRewardsMembership" } }, "object": { "type": "string", "const": "rewards_examine_result", "description": "Object type marker. Always `rewards_examine_result`." } } } }, "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" }, "X-App-Id": { "type": "apiKey", "name": "X-App-Id", "in": "header" }, "X-App-Token": { "type": "apiKey", "name": "X-App-Token", "in": "header" } } }, "security": [ { "bearerAuth": [], "X-App-Id": [], "X-App-Token": [] } ] }