Quality Scores
Every flight offer returned by the Norba API carries a quality_score field — a number between 0.0 and 1.0 that reflects how complete and reliable the offer is. This page explains how that score is calculated.
Why quality scores?
In the fragmented world of NDC, different airlines return varying levels of detail. Some might omit aircraft types, others might omit fare rules entirely. A quality score gives you an immediate, objective signal about how much usable data an offer contains — without having to inspect every field.
The scorer evaluates each offer against a weighted rubric: critical booking fields (offer ID, airline, price, itinerary) carry the most weight, while enrichable fields (cabin class, aircraft type) contribute less. A score of 1.0 means the offer is complete according to the Norba schema.
Scoring tiers
Fields are grouped into three tiers, each with a different weight multiplier:
Without these the offer cannot be booked. Missing any critical field drops the score significantly.
Required for a good user experience. These fields drive the booking UI, fare display, and passenger summary.
Nice-to-have enrichments. Often filled by Norba's refdata layer if the airline does not supply them.
Segment-level scoring
Each slice and segment is also scored dynamically based on the itinerary complexity:
| Field | Weight | Why it matters |
|---|---|---|
| departure_utc | 3× | Without departure time the passenger cannot check in. |
| arrival_utc | 3× | Required for itinerary clarity and connections. |
| duration_minutes | 2× | Helps passengers gauge layover and total travel time. |
| flight_number | 2× | Identifies the specific service to the passenger. |
| aircraft | 1× | Nice-to-have; can be enriched from refdata. |
| booking_class | 1× | Used for fare branding and upgrade eligibility. |
Formula
The quality score is a simple weighted ratio:
quality_score = earned_weight / total_weight
The score is capped at 1.0. If every field is present, the score is 1.0 regardless of how many fields are evaluated.
1Each present field earns its weight. Missing fields earn 0.
2Sum the earned weight across all fields (offer-level + segment-level).
3Divide earned weight by the total possible weight.
Example
Here's a worked example for a typical American Airlines economy offer from JFK to LHR:
Offer {
offer_id: "aa_offer_abc123" ✓ 3×
airline: "American Airlines" ✓ 3×
slices: [1 slice] ✓ 3×
total_amount: 542.10 ✓ 3×
currency: "EUR" ✓ 3×
expires_at: "2026-06-21T12:30Z" ✓ 3×
passengers: [1 pax] ✓ 2×
base_fare: 410.00 ✓ 2×
taxes_fees: 132.10 ✓ 2×
source_version:"NDC 21.3" ✓ 2×
fare_rules: { ... } ✓ 2×
fare_family: "Standard" ✓ 1×
cabin_class: "Economy" ✓ 1×
baggage: true ✓ 1×
Slice duration: 420 min ✓ 2×
Segment count: 1 ✓ 3×
Flight number: "BA178" ✓ 2×
Departure UTC: 2026-06-21T06:00Z ✓ 3×
Arrival UTC: 2026-06-21T12:00Z ✓ 3×
Duration: 360 min ✓ 2×
Aircraft: "A380" ✓ 1×
Booking class: "M" ✓ 1×
}
────────────────────────────────────────
Earned: 38 / Total: 38 = 1.00How to use quality scores
The quality_score field lives on every Offer object returned by the Norba API. Here are practical ways to use it:
- Sort search results by score so the most complete offers appear first.
- Surface a visual indicator (e.g. a gauge or badge) next to each offer in your UI.
- Filter out offers below a threshold (e.g. < 0.5) in automated booking pipelines.
- Log score distributions to monitor airline data quality over time.