A valid request URL is required to generate request examples{
"id": "promo-bundle-tshirt-cap",
"type": "bundle",
"validFrom": "2026-01-01T00:00:00.000Z",
"validUntil": "2026-12-31T00:00:00.000Z"
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123,
"fieldErrors": [
{
"field": "<string>",
"message": "<string>"
}
]
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}Update an existing promotion rule
REPLACES one existing automatic promotion rule wholesale, addressed by the path id. Unlike POST /v1/promotions (which upserts), this NEVER creates: an unknown id 404s rather than minting a rule, so it is the safe verb when you mean to edit one that is already live. The path id is authoritative — any id in the body is overwritten, so you cannot retarget the edit onto another rule. Every other field is a FULL REPLACE, exactly like the upsert: each field absent from your body is destroyed, including the reward mechanics. Read the live rule from GET /v1/promotions/{id}/rule first, change only what you were asked to change, and send the whole object back; if that read 404s (no rule configured) this PUT 404s too — STOP and ask rather than reconstruct plausible values. Pick type and express money as integer CENTS, percentages as BASIS POINTS (1000 = 10%); validUntil must not precede validFrom. To stop a rule instead of editing it, use POST /v1/promotions/{id}/deactivate.
A valid request URL is required to generate request examples{
"id": "promo-bundle-tshirt-cap",
"type": "bundle",
"validFrom": "2026-01-01T00:00:00.000Z",
"validUntil": "2026-12-31T00:00:00.000Z"
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123,
"fieldErrors": [
{
"field": "<string>",
"message": "<string>"
}
]
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}{
"error": {
"code": "VALIDATION_FAILED",
"message": "<string>",
"statusCode": 123
}
}Authorizations
Authorization: Bearer <token>. Accepts EITHER a Keycloak access token (scopes-in-token) OR an opaque POS session token; both resolve to the same pos.* scope vocabulary the route guards enforce.
Path Parameters
1Body
- Option 1
- Option 2
- Option 3
1^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$bogo ^[0-9a-f]{64}$0 < x <= 9007199254740991^[0-9a-f]{64}$0 < x <= 90071992547409911 <= x <= 10000Response
The replaced rule, echoed back with its validity window as ISO instants. The example shows a bundle rule (fixed price for a set of components); see setPromotion for the bogo shape.
- Option 1
- Option 2
- Option 3
The replaced rule, echoed back with its validity window as ISO instants. The example shows a bundle rule (fixed price for a set of components); see setPromotion for the bogo shape.
1^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z|([+-](?:[01]\d|2[0-3]):[0-5]\d)))$bogo ^[0-9a-f]{64}$0 < x <= 9007199254740991^[0-9a-f]{64}$0 < x <= 90071992547409911 <= x <= 10000
