Tutorial · Finance handoff
Build a reconciliation-ready booking ledger.
Finance cannot reconcile a hotel folio or supplier invoice if the booking record has no operational context. This tutorial shows how to collect the identifiers, rates, and status evidence available in v1 and hand them into your existing reconciliation process.
Updated Current v1 tutorial; invoice and folio ingestion is planned
Implementation summary
- Trigger
- A completed or stopped schedule run, followed by the supplier invoice or hotel folio.
- Current v1 input
- Schedule action CSV, booking records, rate evidence, status history, and audit events.
- Human boundary
- Invoice ingestion, document matching, approval, and supplier disputes remain in the finance system today.
- Result
- A controlled ledger that explains each charge through booking and airline operational identifiers.
The real-life scenario
A crew hotel invoice arrives after a schedule change. Finance needs to know which room was requested, which hotel confirmed it, what the contracted and booked rates were, whether the stay was later modified or cancelled, and which pairing created the need. The booking ledger supplies that context before the invoice line is approved or disputed.
Use stable join keys, not descriptions
booking_idPrimary Routespring booking record. Keep it on every downstream finance row.
schedule_id and external_refTie charges back to the submitted roster window and airline export.
employee_id and pairing_numberConnect the booking to crew operations without relying on free text.
duty_date and flight_numberExplain when and why the travel was required.
supplier confirmationMatch a supplier folio or invoice to the confirmed reservation.
contracted_rate and booked_rateFlag price variance before invoice comparison begins.
irop_refGroup disruption-driven bookings for event-level cost review.
status historyExplain changes, cancellations, failed attempts, and the final operational state.
1. Collect the operational evidence
Run this after schedule processing stops. Store the raw export and API responses before transforming them so finance can trace any derived record back to the source.
# Export one row per action for airline BI or a finance staging table.
curl -sS "$BASE/crew/schedules/$SCHEDULE_ID/actions.csv" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-o "routespring-$SCHEDULE_ID-actions.csv"
# Retrieve the current booking records tied to the schedule.
curl -sS -G "$BASE/crew/bookings" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
--data-urlencode "schedule_id=$SCHEDULE_ID" \
--data-urlencode "limit=100" \
-o "routespring-$SCHEDULE_ID-bookings.json"
# Preserve data-quality and duplicate findings from the source schedule.
curl -sS "$BASE/crew/schedules/$SCHEDULE_ID/audit-events" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-o "routespring-$SCHEDULE_ID-audit-events.json"2. Flag booking-rate variance
A difference between contracted_rate and booked_rate is an operational variance worth reviewing before a folio arrives. Keep currency mismatches and missing rates in a review queue instead of treating them as zero variance.
type Money = { amount: number; currency: string };
function rateVariance(
contracted: Money | null | undefined,
booked: Money | null | undefined,
) {
if (!contracted || !booked || contracted.currency !== booked.currency) {
return { status: "REVIEW", reason: "Missing or mismatched rate evidence" };
}
const amount = booked.amount - contracted.amount;
return {
status: amount === 0 ? "MATCHED" : "VARIANCE",
amount,
currency: booked.currency,
};
}3. Join the supplier document in your finance system
- 1
Match the reservation
Use the supplier confirmation first, then booking ID, crew and stay dates, property, and pairing as supporting keys.
- 2
Compare the commercial record
Check room dates, booked rate, contracted rate, taxes, fees, incidentals, cancellation state, and invoice total.
- 3
Classify the variance
Separate wrong rate, duplicate charge, unauthorized incidental, no-show, cancellation fee, tax, and missing-folio cases.
- 4
Preserve the decision
Store the source booking IDs, evidence, reviewer, approval or dispute status, and final amount paid.
4. Treat exceptions as an owned queue
- Do not pay against a PENDING, FAILED, NEEDS_REVIEW, or cancelled booking without reviewing the final supplier record.
- Keep data-quality and duplicate audit events beside the schedule that produced the booking set.
- Refresh booking status before a payment run when the operational record may have changed.
- Use irop_ref to report disruption costs separately from scheduled crew travel.
- Reconcile in pages when a schedule returns more bookings than the API limit.
Plan for the next API layer
The planned reconciliation family is intended to move invoice and folio ingestion, line-level matching, variance state, supporting documents, and dispute handoff into the API. Its shape and availability may change. Build production integrations only against the current OpenAPI contract.