# Refunds, changes & schedule changes

After ticketing, changes go through **servicing requests**: you ask, our ticketing desk gets the airline's conditions and sends you a **quote**, you accept or decline. Nothing is charged or refunded until you accept.

## Request types

| `type` | Use when | Typical cost |
|---|---|---|
| `void` | Cancel on the **day of issue** (before `deadlines.voidUntil`). | Usually free. |
| `refund` | Cancel the whole booking or some passengers/slices. | Airline penalty per the fare rules; non-refundable fares refund nothing (or taxes only). |
| `no_show_refund` | The passenger did not fly; recover refundable taxes. | Depends on the airline. |
| `change_date` | Move to another date (`requestedDate`). | Change penalty + fare difference. |
| `other` | Anything else (name correction, special request) — explain in `note`. | Quoted case by case. |

## Flow

```
requested ──► in_review ──► quoted ──accept──► accepted ──► executing ──► completed
                 │             ├──decline──► declined
                 │             └──(expires)─► quote_expired
                 └──► rejected (the desk/airline refused; see history)
(any time before accepting) ──withdraw──► withdrawn
executing ──► failed (rare; the desk follows up)
```

### 1. Create a request

```bash
curl -X POST $TAM_URL/flights/bookings/7c1e.../post-booking-requests \
  -H "Authorization: Bearer $TAM_KEY" -H "Content-Type: application/json" -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "type": "refund", "passengerIndexes": [0], "note": "Customer cancelled" }'
```

- `passengerIndexes` / `sliceIndexes` — from `passengers[].index` and the slice order; empty means all.
- One open request per booking at a time (`flights.servicing_request_open`).
- Scope: `flights:post_booking`.

### 2. Receive the quote

Wait for the `flight.post_booking_request.updated` webhook (or poll `GET …/post-booking-requests/{requestId}`). When `status` is `quoted`:

```json
{
  "id": "5e2d…", "requestNumber": "PBR-…", "type": "refund", "status": "quoted",
  "quote": {
    "airlinePenalty": { "amount": "18.00", "currency": "USD" },
    "serviceFee":     { "amount": "0.00",  "currency": "USD" },
    "fareDifference": { "amount": "0.00",  "currency": "USD" },
    "refundAmount":   { "amount": "162.00", "currency": "USD" },
    "collectAmount":  { "amount": "0.00",  "currency": "USD" },
    "expiresAt": "2026-11-21T10:00:00Z"
  },
  "nextActions": [
    { "action": "accept_quote",  "method": "POST", "href": "/flights/bookings/7c1e…/post-booking-requests/5e2d…/accept",  "deadline": "2026-11-21T10:00:00Z" },
    { "action": "decline_quote", "method": "POST", "href": "/flights/bookings/7c1e…/post-booking-requests/5e2d…/decline", "deadline": "2026-11-21T10:00:00Z" },
    { "action": "withdraw", … }
  ]
}
```

- `refundAmount` is credited to your wallet, `collectAmount` is charged to it, when you accept.
- The booking shows `pendingReason: awaiting_quote_decision` meanwhile.

### 3. Accept or decline

```bash
curl -X POST $TAM_URL/flights/bookings/7c1e.../post-booking-requests/5e2d.../accept \
  -H "Authorization: Bearer $TAM_KEY" -H "Idempotency-Key: $(uuidgen)"
```

After acceptance the desk executes the change with the airline. On `completed`, `outcome` shows what was refunded or collected, and for a change the `newPnr` / `newBookingId`. The booking updates accordingly: a full refund makes it `cancelled`; a partial one marks the passengers `cancelled` in `passengers[].state`.

Decline with `POST …/decline` (optional `{ "note": "…" }`); withdraw a request you no longer need with `POST …/withdraw`.

## Schedule changes

Airlines change flight times, numbers or routings after ticketing. When that happens:

1. You receive `flight.booking.schedule_changed`, and the booking lists the notice in `openScheduleChanges`.
2. `GET /flights/bookings/{id}/schedule-changes` shows the original and the new segments, `requiresAcceptance` and `replyDeadline`.
3. Then:
   - **No acceptance needed** (information only): `POST …/schedule-changes/{id}/acknowledge`.
   - **Acceptance needed**: inform the passenger, then `POST …/schedule-changes/{id}/accept` before `replyDeadline`. The booking shows `pendingReason: awaiting_schedule_change_reply` until then.
   - **Passenger refuses the new schedule**: do not accept; create a `refund` or `change_date` request instead — an involuntary change usually waives penalties.

## Errors you may see

| Code | Meaning |
|---|---|
| `flights.use_post_booking_request` | You called `cancel` on a ticketed booking — create a servicing request instead. |
| `flights.servicing_request_open` | Another request is still open on this booking. |
| `flights.booking_not_serviceable` | The booking's status does not allow this request (e.g. not ticketed). |
| `flights.quote_expired` | The quote's deadline passed; create a new request. |
| `flights.schedule_change_not_supported` | The airline does not accept replies through the API for this change; contact support. |
