publ betaReference (MCP guide)
Open publ console

ticket_discount_settings_apply

# ticket_discount_settings_apply

Changes a discount policy (names and labels, sales conditions, discount prices and tier links) or deletes selected discounts, as the console discount screens allow. Discount prices cannot exceed the base prices. Called without confirmToken it previews and returns a confirmToken; repeating the same input with it executes once.

## Inputs

| Field | Required here | Contract |
| --- | --- | --- |
| `eventId` | Yes | string; min length 1; max length 160; pattern `^[A-Za-z0-9_-]+$`; Exact resource identifier returned by this operation, never a title, unrelated row ID or URL. |
| `policyId` | No | string; min length 1; max length 160; pattern `^[A-Za-z0-9_-]+$`; Exact resource identifier returned by this operation, never a title, unrelated row ID or URL. |
| `operation` | Yes | one of: `tierPrice`, `tierLink`, `tierUnlink`, `metadata`, `salesTerms`, `delete` (by `kind`) |
| `operation.eventPolicyTierPriceId` | Yes | When `operation.kind` is `tierPrice`: string; min length 1; max length 160; pattern `^[A-Za-z0-9_-]+$`; Exact resource identifier returned by this operation, never a title, unrelated row ID or URL. |
| `operation.payment` | Yes | When `operation.kind` is `tierPrice`: one of: `free`, `paid` (by `kind`) |
| `operation.payment.amount` | Yes | When `operation.kind` is `tierPrice` and `operation.payment.kind` is `paid`: string; pattern `^(0\|[1-9]\d{0,9})(\.\d{1,2})?$` |
| `operation.tierLabelId` | Yes | When `operation.kind` is `tierLink`: string; min length 1; max length 160; pattern `^[A-Za-z0-9_-]+$`; Exact resource identifier returned by this operation, never a title, unrelated row ID or URL. |
| `operation.payment` | Yes | When `operation.kind` is `tierLink`: one of: `free`, `paid` (by `kind`) |
| `operation.payment.amount` | Yes | When `operation.kind` is `tierLink` and `operation.payment.kind` is `paid`: string; pattern `^(0\|[1-9]\d{0,9})(\.\d{1,2})?$` |
| `operation.eventPolicyTierPriceIds` | Yes | When `operation.kind` is `tierUnlink`: array; items: string; min length 1; max length 160; pattern `^[A-Za-z0-9_-]+$`; Exact resource identifier returned by this operation, never a title, unrelated row ID or URL.; min items 1; max items 100 |
| `operation.confirmation` | Yes | When `operation.kind` is `tierUnlink`: `UNLINK_TIER_PRICES` |
| `operation.settings` | Yes | When `operation.kind` is `metadata`: object |
| `operation.settings.title` | No | When `operation.kind` is `metadata`: string; min length 3; max length 50; pattern `^[^\r\n]*$` |
| `operation.settings.presentationalTitle` | No | When `operation.kind` is `metadata`: string; min length 3; max length 50; pattern `^[^\r\n]*$` |
| `operation.settings.labelIds` | No | When `operation.kind` is `metadata`: array; items: string; min length 1; max length 160; pattern `^[A-Za-z0-9_-]+$`; Exact resource identifier returned by this operation, never a title, unrelated row ID or URL.; max items 10 |
| `operation.settings` | Yes | When `operation.kind` is `salesTerms`: object |
| `operation.settings.languages` | No | When `operation.kind` is `salesTerms`: array; items: `ko`, `en`, `ja`, `zh-cn`, `zh-tw`, `fr`, `es`, `de`, `ru`, `pt`, `it`, `ar`, `hi`, `bn`, `vi`, `id`, `th`, `tr`, `fa`, `pl`, `others`; min items 1; max items 21 or null |
| `operation.settings.codes` | No | When `operation.kind` is `salesTerms`: array; items: string; pattern `^[a-z0-9]{2,20}$`; min items 1; max items 10 or null |
| `operation.settings.purchaseUnit` | No | When `operation.kind` is `salesTerms`: integer; minimum 1; maximum 20 or null |
| `operation.settings.minimumQuantity` | No | When `operation.kind` is `salesTerms`: integer; minimum 2; maximum 100 or null |
| `operation.policyIds` | Yes | When `operation.kind` is `delete`: array; items: string; min length 1; max length 160; pattern `^[A-Za-z0-9_-]+$`; Exact resource identifier returned by this operation, never a title, unrelated row ID or URL.; min items 1; max items 100 |
| `operation.confirmation` | Yes | When `operation.kind` is `delete`: `DELETE_DISCOUNT_POLICIES` |
| `confirmToken` | No | string; pattern `^ct[a-f\d]{32}$`; The confirmToken from this tool's preview result. Omit it to preview; repeat the same input with it to execute. |

## Usage

Give the `eventId`, the `policyId` and one `operation` (`metadata`, `salesTerms`, `tierPrice`, `tierLink` or `tierUnlink`), as described in [ticket_discount_settings_get](ticket_discount_settings_get.md). To delete, give `operation:{kind:"delete", policyIds, confirmation:"DELETE_DISCOUNT_POLICIES"}` without `policyId`.

```json
{"eventId": "event-example", "policyId": "discount-example", "operation": {"kind": "metadata", "settings": {"title": "Early booking", "labelIds": []}}}
```

```json
{"eventId": "event-example", "policyId": "discount-example", "operation": {"kind": "tierPrice", "eventPolicyTierPriceId": "override-example", "payment": {"kind": "paid", "amount": "20000"}}}
```

```json
{"eventId": "event-example", "operation": {"kind": "delete", "policyIds": ["discount-example"], "confirmation": "DELETE_DISCOUNT_POLICIES"}}
```

## Effects

- Names and labels are saved with the complete form: both final names and the complete label selection. `labelIds:[]` removes this discount's links without deleting the labels.
- Sales conditions are saved as the complete merged set; omitted and unknown conditions stay. `null` for languages or codes turns them off, as do `null` and `1` for `purchaseUnit` and `null` for `minimumQuantity`.
- A price change keeps the tier; a free price is saved as `0`. A paid price cannot exceed the base price for the same tier label. Base prices and tier labels are not changed.
- A new price link is complete only with the new price's identity from the service's answer (`createdTierPriceId`); without it the task stays pending and the price is never matched by label or created again.
- Removing prices removes only the selected discount prices, not base prices or tier labels. A partial removal is never sent again for the rest.
- Deleting removes the selected discounts in one request. It is complete when they are gone from the complete active list and the default policy, the other discounts and the event are unchanged. The default policy cannot be deleted; a selection already gone is refused. Deleted discounts cannot be restored here.

Readback also checks that the default policy and its prices, other discounts and the event's cancellation fields are unchanged. It does not show what a customer will pay, and existing schedules and issued tickets are not changed.

## Console screens

The result links the matching console screen: the event's discount list (page 1) for names, labels and deletion, the discount's conditions screen for sales conditions, and its tiered pricing screen for prices.

## Preview and execution

Call the tool without `confirmToken` first. It reads the current state, checks the change and returns a preview: the request it would send (`request:null` when nothing would change), the current values, a `confirmToken`, `confirmTokenExpiresAt` and `writesPerformed:false`. Nothing is saved. Show the preview to the person; after they agree, call the tool again with exactly the same input and that `confirmToken`. The token works once, for this input only, within 10 minutes.

Nothing is sent when the input differs from the preview (`CONFIRM_TOKEN_INPUT_CHANGED`), the token expired (`CONFIRM_TOKEN_EXPIRED`) or belongs to another tool or channel (`CONFIRM_TOKEN_INVALID`), or the current state changed after the preview (`COMMERCE_CONFLICT` or `COMMERCE_CHANGED`). Call the tool again with the intended input to get a new preview.

## Results and recovery

`COMMERCE_OPERATION_COMPLETE` means two fresh reads matched the requested change and the other returned values stayed as they were; `noop:true` means nothing needed to change and nothing was sent. `COMMERCE_OPERATION_PENDING` means the change was sent but could not be confirmed (see `lastCode`); `COMMERCE_JOURNAL_PERSISTENCE_FAILED` means the saved progress itself is uncertain. `writesPerformed` is false when nothing was sent, true after the service acknowledged the change and null when a sent change was not acknowledged.

The result carries a `taskId` (task type `commerce-ticket-discount-settings`). Observe it with [task_status](publ_task_status.md) or [task_resume](publ_task_resume.md); both only read. An uncertain execution is never sent again: resolve it before previewing the same change again. Repeating the same input with the same `confirmToken` returns to that task and never resends what was already sent. A completed result returned again later is the stored result, not the current state; read current values with [ticket_discount_settings_get](ticket_discount_settings_get.md). There is no automatic rollback; undoing a change is a new change with its own preview.

Deletions are kept under task type `commerce-ticket-policy-lifecycle`.

## Not offered here

Creating or copying discounts, translations, editing management labels themselves ([ticket_policy_label_apply](ticket_policy_label_apply.md)), coupon generation, payment, refund and settlement.