# telecoms.call-rating Rates one call record (CDR) against a rate deck the way telecoms billing does it, in four steps: 1. **Destination by longest prefix.** The dialled number is matched against every prefix in the deck and the longest match wins, so 447700900123 matches `447` (UK mobile) rather than `44` (UK fixed). Numbers are in international format, E.164 digits with or without a leading `+`; convert national numbers (07700 900123) before rating. No match is an error: silently rating an unknown destination at zero is how fraud traffic goes unbilled. 2. **Billing increments.** An increment is written first/next: 60/60 is per minute, 30/6 is a 30-second minimum then 6-second blocks, 1/1 is per second. The duration is rounded up to them: 61 seconds on 60/60 is 120 billed seconds; 125 seconds on 30/6 is 126. 3. **Charge.** perMinute x billedSeconds / 60, rounded once to a whole minor unit by the caller's `mode` (math.round-div), plus the connection fee. Operators differ on how they round fractions of a penny, so it is an argument rather than a hidden choice. 4. **Minimum charge.** If the result is below the minimum call charge, the minimum is charged. The minimum includes the connection fee. An unanswered call (0 seconds) is not charged at all: no connection fee, no minimum. Prices are per minute in minor units, so a rate of 0.5p a minute cannot be written; use a deck in a smaller currency unit if you need one. The rate deck is an argument because every operator has its own and changes it often; this capability holds no rates of its own. Deck rows are checked on every call: prefixes must be digits and unique, increments at least 1 second, and every price in one currency. Errors: no matching prefix, a dialled number that is not digits, a negative duration, a duplicate or non-numeric prefix, an increment below 1, mixed currencies, and an unknown rounding mode. 1.0.1 fixes Python accepting a trailing newline in dialledNumber and a rate's prefix; adds tests.