Changes and cancellations
Passenger-level change impact. Preview or apply the removal of passengers, the cancellation of a cabin or of a whole purchase order, with fees, refunds and re-allocation computed per passenger.
| Operation | Endpoint |
|---|---|
| Apply a change | POST /oms-ops/changes |
| Preview a change | POST /oms-ops/changes/preview |
Apply a change
/oms-ops/changesApplies the change. Purchase orders receive an order change (and are cancelled when every line falls to zero), allocation is re-run, and money no longer needed is refunded to the payments it came from. Idempotent on the Idempotency-Key header or body idempotencyKey.
Headers: Idempotency-Key, plus X-Request-Id.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
tripId | string | yes | 1–200 chars |
kind | enum: remove_passengers, cancel_cabin, cancel_purchase_order | yes | |
passengers | array of string | remove_passengers: the passengers leaving the trip (required, non-empty). | |
lineId | string | cancel_cabin: the cabin line; its passengers leave the trip. | |
poId | string | cancel_purchase_order: the order cancelled; the trip's other orders stay. | |
reason | string | yes | 1–500 chars |
asOf | string (date-time) | The date the cancellation tier is read at. Default now. | |
actor | object | yes | |
actor.channel | string | max 60 chars | |
actor.id | string | yes | 1–200 chars |
actor.name | string | max 200 chars | |
actor.role | string | yes | 1–100 chars |
idempotencyKey | string | 1–200 chars |
Schema: Source apps/journeys/src/oms-ops/change-impact.ts (ChangeRequestSchema).
Response 201
/oms-ops/changesCancel the excursion order; the money paid on it is refundedcurl -X POST "$BASE/oms-ops/changes" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Request-Id: req-0012" \
-H "Idempotency-Key: 3387b41a-0391-4bf1-ab15-94130a843671" \
-H "Content-Type: application/json" \
-d '{
"tripId": "TRP-B2BD5A9771E4",
"kind": "cancel_purchase_order",
"poId": "PO-71B4D4926EDD",
"reason": "Guest changed shore plans",
"asOf": "2026-11-20T10:00:00Z",
"actor": {
"id": "agent-0412",
"name": "Marco Bianchi",
"role": "care_agent",
"channel": "contact_centre"
}
}'
HTTP/1.1 201
X-Request-Id: req-0012
{
"changeId": "chg_816c2c9911ef9df067ce",
"mode": "applied",
"tripId": "TRP-B2BD5A9771E4",
"kind": "cancel_purchase_order",
"reason": "Guest changed shore plans",
"asOf": "2026-11-20T10:00:00Z",
"departureAt": "2027-04-12T17:00:00Z",
"daysBeforeDeparture": 143,
"currency": "EUR",
"passengers": [
{
"passengerRef": "PAX-01",
"passengerName": null,
"leaves": false,
"units": [
{
"lineId": "L-FDAF4DA2CF1A",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"passengerRef": "PAX-01",
"passengerName": null,
"cancelled": true,
"policy": {
"id": "refundable",
"label": "Refundable before departure",
"source": "product_kind",
"tier": {
"minDaysBefore": 0,
"feePercent": 0,
"feeMinorPerPassenger": 0
}
},
"priceMinor": 8900,
"paidMinor": 8900,
"feeMinor": 0,
"retainedMinor": 0,
"refundMinor": 8900,
"heldMinor": 0,
"reappliedOutMinor": 0,
"reappliedInMinor": 0,
"openMinor": 0
}
],
"priceMinor": 8900,
"paidMinor": 8900,
"feeMinor": 0,
"refundMinor": 8900,
"heldMinor": 0,
"reappliedOutMinor": 0,
"reappliedInMinor": 0,
"openMinor": 0
},
{
"passengerRef": "PAX-02",
"passengerName": null,
"leaves": false,
"units": [
{
"lineId": "L-FDAF4DA2CF1A",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"passengerRef": "PAX-02",
"passengerName": null,
"cancelled": true,
"policy": {
"id": "refundable",
"label": "Refundable before departure",
"source": "product_kind",
"tier": {
"minDaysBefore": 0,
"feePercent": 0,
"feeMinorPerPassenger": 0
}
},
"priceMinor": 8900,
"paidMinor": 8900,
"feeMinor": 0,
"retainedMinor": 0,
"refundMinor": 8900,
"heldMinor": 0,
"reappliedOutMinor": 0,
"reappliedInMinor": 0,
"openMinor": 0
},
{
"lineId": "L-93A9D925FCE1",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"passengerRef": "PAX-02",
"passengerName": null,
"cancelled": true,
"policy": {
"id": "refundable",
"label": "Refundable before departure",
"source": "product_kind",
"tier": {
"minDaysBefore": 0,
"feePercent": 0,
"feeMinorPerPassenger": 0
}
},
"priceMinor": 6900,
"paidMinor": 6900,
"feeMinor": 0,
"retainedMinor": 0,
"refundMinor": 6900,
"heldMinor": 0,
"reappliedOutMinor": 0,
"reappliedInMinor": 0,
"openMinor": 0
}
],
"priceMinor": 15800,
"paidMinor": 15800,
"feeMinor": 0,
"refundMinor": 15800,
"heldMinor": 0,
"reappliedOutMinor": 0,
"reappliedInMinor": 0,
"openMinor": 0
}
],
"reappliedTo": [],
"lines": [
{
"lineId": "L-BB4F731FB7C8",
"poId": "PO-5BEE8AAD2A57",
"productKind": "beverage",
"oldAmountMinor": 30800,
"newAmountMinor": 30800,
"paidBeforeMinor": 0,
"paidAfterMinor": 0,
"changed": false
},
{
"lineId": "L-A610167BDD4D",
"poId": "PO-5BEE8AAD2A57",
"productKind": "cruise",
"oldAmountMinor": 238000,
"newAmountMinor": 238000,
"paidBeforeMinor": 53760,
"paidAfterMinor": 53760,
"changed": false
},
{
"lineId": "L-FDAF4DA2CF1A",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"oldAmountMinor": 17800,
"newAmountMinor": 0,
"paidBeforeMinor": 17800,
"paidAfterMinor": 0,
"changed": true
},
{
"lineId": "L-93A9D925FCE1",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"oldAmountMinor": 6900,
"newAmountMinor": 0,
"paidBeforeMinor": 6900,
"paidAfterMinor": 0,
"changed": true
}
],
"purchaseOrders": [
{
"poId": "PO-5BEE8AAD2A57",
"changed": false,
"cancelled": false,
"oldTotalMinor": 268800,
"newTotalMinor": 268800
},
{
"poId": "PO-71B4D4926EDD",
"changed": true,
"cancelled": true,
"oldTotalMinor": 24700,
"newTotalMinor": 0
}
],
"payments": [
{
"paymentId": "pay_f64cf55a-93e1-4f1e-bdbd-2f1ae6d5ee6b",
"anchor": {
"ref": "PO-71B4D4926EDD",
"level": "purchase_order"
},
"scenario": "ancillary_purchase",
"releasedMinor": 24700,
"reappliedMinor": 0,
"refundMinor": 24700,
"heldMinor": 0
}
],
"refunds": [
{
"paymentId": "pay_8107cc9e-34c3-48ab-bd3b-0a00c4e42db2",
"refundOf": "pay_f64cf55a-93e1-4f1e-bdbd-2f1ae6d5ee6b",
"amountMinor": 24700
}
],
"reallocationRunId": "realloc_6ba19cf0-316e-4e98-91d7-c3e88043ab26",
"reconciliation": {
"paidMinor": 24700,
"feesRetainedMinor": 0,
"refundMinor": 24700,
"heldMinor": 0,
"reappliedMinor": 0,
"receivedMinor": 0,
"balanced": true,
"trip": {
"amountBeforeMinor": 293500,
"amountAfterMinor": 268800,
"paidBeforeMinor": 78460,
"paidAfterMinor": 53760,
"offLinesMinor": 24700,
"balanced": true
}
},
"idempotent": false
}
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 400 | idempotency_key_mismatch | The Idempotency-Key header and the body idempotencyKey differ. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 403 | scope_forbidden | The token is scoped to an agency or an access scope; this surface requires an unscoped tenant token. |
| 404 | change_impact_not_enabled | The change-impact policy section is not configured for the tenant. |
| 404 | trip_not_found | The trip has no order lines in the projection. |
| 404 | oms_ops_not_enabled | Order operations are not enabled for the tenant. |
| 409 | idempotency_in_progress | A request with this Idempotency-Key is still running. Retry after the Retry-After interval. |
| 422 | departure_unknown | The trip's departure date is unknown, so no cancellation tier applies. |
| 422 | unknown_purchase_order | The purchase order is not on the trip. |
| 422 | unknown_line | A line named in the request is not on the order. |
| 422 | unknown_passenger | A passenger named in the change is not on the trip. |
| 422 | nothing_to_change | The change would not alter any line. |
| 422 | idempotency_key_reused | The Idempotency-Key was used for a different request. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |
Preview a change
/oms-ops/changes/previewComputes the impact of removing passengers, cancelling a cabin or cancelling a purchase order, per passenger and per line, with fees from the tenant's cancellation tiers, refunds and re-applied money. Writes nothing.
Headers: Idempotency-Key, plus X-Request-Id.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
tripId | string | yes | 1–200 chars |
kind | enum: remove_passengers, cancel_cabin, cancel_purchase_order | yes | |
passengers | array of string | remove_passengers: the passengers leaving the trip (required, non-empty). | |
lineId | string | cancel_cabin: the cabin line; its passengers leave the trip. | |
poId | string | cancel_purchase_order: the order cancelled; the trip's other orders stay. | |
reason | string | yes | 1–500 chars |
asOf | string (date-time) | The date the cancellation tier is read at. Default now. | |
actor | object | yes | |
actor.channel | string | max 60 chars | |
actor.id | string | yes | 1–200 chars |
actor.name | string | max 200 chars | |
actor.role | string | yes | 1–100 chars |
idempotencyKey | string | 1–200 chars |
Schema: Source apps/journeys/src/oms-ops/change-impact.ts (ChangeRequestSchema).
Response 200
/oms-ops/changes/previewPreview cancelling one passengercurl -X POST "$BASE/oms-ops/changes/preview" \
-H "Authorization: Bearer $TOKEN" \
-H "X-Request-Id: req-0011" \
-H "Content-Type: application/json" \
-d '{
"tripId": "TRP-B2BD5A9771E4",
"kind": "remove_passengers",
"passengers": [
"PAX-02"
],
"reason": "Guest can no longer travel",
"asOf": "2026-11-20T10:00:00Z",
"actor": {
"id": "agent-0412",
"name": "Marco Bianchi",
"role": "care_agent",
"channel": "contact_centre"
}
}'
HTTP/1.1 200
X-Request-Id: req-0011
{
"changeId": "chg_9356355f3e5c3b91efd7",
"mode": "preview",
"tripId": "TRP-B2BD5A9771E4",
"kind": "remove_passengers",
"reason": "Guest can no longer travel",
"asOf": "2026-11-20T10:00:00Z",
"departureAt": "2027-04-12T17:00:00Z",
"daysBeforeDeparture": 143,
"currency": "EUR",
"passengers": [
{
"passengerRef": "PAX-02",
"passengerName": null,
"leaves": true,
"units": [
{
"lineId": "L-BB4F731FB7C8",
"poId": "PO-5BEE8AAD2A57",
"productKind": "beverage",
"passengerRef": "PAX-02",
"passengerName": null,
"cancelled": true,
"policy": {
"id": "refundable",
"label": "Refundable before departure",
"source": "product_kind",
"tier": {
"minDaysBefore": 0,
"feePercent": 0,
"feeMinorPerPassenger": 0
}
},
"priceMinor": 15400,
"paidMinor": 0,
"feeMinor": 0,
"retainedMinor": 0,
"refundMinor": 0,
"heldMinor": 0,
"reappliedOutMinor": 0,
"reappliedInMinor": 0,
"openMinor": 0
},
{
"lineId": "L-A610167BDD4D",
"poId": "PO-5BEE8AAD2A57",
"productKind": "cruise",
"passengerRef": "PAX-02",
"passengerName": null,
"cancelled": true,
"policy": {
"id": "cruise-fare",
"label": "Cruise fare",
"source": "default",
"tier": {
"minDaysBefore": 90,
"feePercent": 10,
"feeMinorPerPassenger": 0
}
},
"priceMinor": 119000,
"paidMinor": 26880,
"feeMinor": 11900,
"retainedMinor": 4887,
"refundMinor": 0,
"heldMinor": 0,
"reappliedOutMinor": 21993,
"reappliedInMinor": 0,
"openMinor": 7013
},
{
"lineId": "L-FDAF4DA2CF1A",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"passengerRef": "PAX-02",
"passengerName": null,
"cancelled": true,
"policy": {
"id": "refundable",
"label": "Refundable before departure",
"source": "product_kind",
"tier": {
"minDaysBefore": 0,
"feePercent": 0,
"feeMinorPerPassenger": 0
}
},
"priceMinor": 8900,
"paidMinor": 8900,
"feeMinor": 0,
"retainedMinor": 0,
"refundMinor": 8900,
"heldMinor": 0,
"reappliedOutMinor": 0,
"reappliedInMinor": 0,
"openMinor": 0
},
{
"lineId": "L-93A9D925FCE1",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"passengerRef": "PAX-02",
"passengerName": null,
"cancelled": true,
"policy": {
"id": "refundable",
"label": "Refundable before departure",
"source": "product_kind",
"tier": {
"minDaysBefore": 0,
"feePercent": 0,
"feeMinorPerPassenger": 0
}
},
"priceMinor": 6900,
"paidMinor": 6900,
"feeMinor": 0,
"retainedMinor": 0,
"refundMinor": 6900,
"heldMinor": 0,
"reappliedOutMinor": 0,
"reappliedInMinor": 0,
"openMinor": 0
}
],
"priceMinor": 150200,
"paidMinor": 42680,
"feeMinor": 11900,
"refundMinor": 15800,
"heldMinor": 0,
"reappliedOutMinor": 21993,
"reappliedInMinor": 0,
"openMinor": 7013
}
],
"reappliedTo": [
{
"lineId": "L-A610167BDD4D",
"poId": "PO-5BEE8AAD2A57",
"productKind": "cruise",
"passengerRef": "PAX-01",
"passengerName": null,
"cancelled": false,
"policy": null,
"priceMinor": 119000,
"paidMinor": 26880,
"feeMinor": 0,
"retainedMinor": 0,
"refundMinor": 0,
"heldMinor": 0,
"reappliedOutMinor": 0,
"reappliedInMinor": 21993,
"openMinor": 70127
}
],
"lines": [
{
"lineId": "L-BB4F731FB7C8",
"poId": "PO-5BEE8AAD2A57",
"productKind": "beverage",
"oldAmountMinor": 30800,
"newAmountMinor": 15400,
"paidBeforeMinor": 0,
"paidAfterMinor": 0,
"changed": true
},
{
"lineId": "L-A610167BDD4D",
"poId": "PO-5BEE8AAD2A57",
"productKind": "cruise",
"oldAmountMinor": 238000,
"newAmountMinor": 130900,
"paidBeforeMinor": 53760,
"paidAfterMinor": 53760,
"changed": true
},
{
"lineId": "L-FDAF4DA2CF1A",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"oldAmountMinor": 17800,
"newAmountMinor": 8900,
"paidBeforeMinor": 17800,
"paidAfterMinor": 8900,
"changed": true
},
{
"lineId": "L-93A9D925FCE1",
"poId": "PO-71B4D4926EDD",
"productKind": "excursion",
"oldAmountMinor": 6900,
"newAmountMinor": 0,
"paidBeforeMinor": 6900,
"paidAfterMinor": 0,
"changed": true
}
],
"purchaseOrders": [
{
"poId": "PO-5BEE8AAD2A57",
"changed": true,
"cancelled": false,
"oldTotalMinor": 268800,
"newTotalMinor": 146300
},
{
"poId": "PO-71B4D4926EDD",
"changed": true,
"cancelled": false,
"oldTotalMinor": 24700,
"newTotalMinor": 8900
}
],
"payments": [
{
"paymentId": "pay_f64cf55a-93e1-4f1e-bdbd-2f1ae6d5ee6b",
"anchor": {
"ref": "PO-71B4D4926EDD",
"level": "purchase_order"
},
"scenario": "ancillary_purchase",
"releasedMinor": 15800,
"reappliedMinor": 0,
"refundMinor": 15800,
"heldMinor": 0
}
],
"refunds": [],
"reallocationRunId": "realloc_3af5ebe1-a1d1-4709-b4ba-d1f4e313709a",
"reconciliation": {
"paidMinor": 42680,
"feesRetainedMinor": 4887,
"refundMinor": 15800,
"heldMinor": 0,
"reappliedMinor": 21993,
"receivedMinor": 0,
"balanced": true,
"trip": {
"amountBeforeMinor": 293500,
"amountAfterMinor": 155200,
"paidBeforeMinor": 78460,
"paidAfterMinor": 62660,
"offLinesMinor": 15800,
"balanced": true
}
}
}
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request failed validation. The message names the first failing field; oms-ops and group surfaces also return every issue in details. |
| 401 | unauthenticated | The bearer token is missing, invalid, expired or minted for another purpose. |
| 403 | scope_forbidden | The token is scoped to an agency or an access scope; this surface requires an unscoped tenant token. |
| 404 | change_impact_not_enabled | The change-impact policy section is not configured for the tenant. |
| 404 | trip_not_found | The trip has no order lines in the projection. |
| 404 | oms_ops_not_enabled | Order operations are not enabled for the tenant. |
| 409 | idempotency_in_progress | A request with this Idempotency-Key is still running. Retry after the Retry-After interval. |
| 422 | departure_unknown | The trip's departure date is unknown, so no cancellation tier applies. |
| 422 | unknown_purchase_order | The purchase order is not on the trip. |
| 422 | unknown_line | A line named in the request is not on the order. |
| 422 | unknown_passenger | A passenger named in the change is not on the trip. |
| 422 | nothing_to_change | The change would not alter any line. |
| 422 | idempotency_key_reused | The Idempotency-Key was used for a different request. |
| 500 | internal | Unexpected failure. Retry with the same Idempotency-Key. |