Routespring Logo
Request Demo

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.

The current v1 API does not ingest invoices or folios and does not open supplier disputes. It provides the operational side of the match: actions, bookings, identifiers, supplier confirmation, rates, status history, data-quality findings, and CSV export. Invoice and folio APIs are planned, not available today.

Use stable join keys, not descriptions

booking_id

Primary Routespring booking record. Keep it on every downstream finance row.

schedule_id and external_ref

Tie charges back to the submitted roster window and airline export.

employee_id and pairing_number

Connect the booking to crew operations without relying on free text.

duty_date and flight_number

Explain when and why the travel was required.

supplier confirmation

Match a supplier folio or invoice to the confirmed reservation.

contracted_rate and booked_rate

Flag price variance before invoice comparison begins.

irop_ref

Group disruption-driven bookings for event-level cost review.

status history

Explain 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.

Terminal
# 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.

Terminal
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. 1

    Match the reservation

    Use the supplier confirmation first, then booking ID, crew and stay dates, property, and pairing as supporting keys.

  2. 2

    Compare the commercial record

    Check room dates, booked rate, contracted rate, taxes, fees, incidentals, cancellation state, and invoice total.

  3. 3

    Classify the variance

    Separate wrong rate, duplicate charge, unauthorized incidental, no-show, cancellation fee, tax, and missing-folio cases.

  4. 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.