# Freight RFQ metrics: instructions for the template

Version 1.0, 8 October 2026. Vektor Group. Reference page: https://vektorgroup.eu/marketing/resources/freight-rfq-metrics

This is our proposed method for measuring marketing from enquiry to booked contribution. It is not an industry standard. We review it every quarter and record each change with its date; the next review is due in January 2027.

## The files

| File | What it holds |
|---|---|
| freight-rfq-metrics-template.csv | The blank record template: a header row with 33 fields, one row per enquiry |
| freight-rfq-metrics-data-dictionary.csv | Each field with its type, definition, allowed values and an invented example |
| freight-rfq-metrics-formulas.csv | The counts, checks and metrics, each with numerator, denominator and the rule for an unavailable value |
| freight-rfq-metrics-instructions.md | This file |

Every example value in the dictionary is invented. None of these files holds Vektor operating data or customer data.

## Keep personal data out

The template has no field for a name, email address, phone number or street address. GDPR Article 4(1) lists a name, an identification number, location data and an online identifier among the identifiers that can make a person identifiable, and Article 5(1)(c) asks for personal data limited to what is necessary. Use account_ref, your own internal company reference, and keep contact details in your CRM.

A filled file is still confidential. It holds your prices and margins, and an internal reference can point to a person, for example a sole trader. Do not publish a filled template.

## One row per enquiry

Every inbound enquiry gets a row: web forms, emails, calls, chat, freight exchange messages and tender portal invitations. Set enquiry_type first. Only shipper_rfq and tender_invitation rows can become RFQs; carrier applications, driver applications, supplier pitches, questions about shipments already moving and spam stay in the file so they can be counted, with exclusion_reason not_rfq.

Dates are written YYYY-MM-DD (ISO 8601), countries as two letter ISO 3166 codes and the currency as a three letter ISO 4217 code. Use the allowed values in the dictionary exactly as written, in lower case.

## Deduplication

A unique RFQ is one shipper's request for a price on one transport need. Keep the earliest record of it as the RFQ, with its acquisition_source. Every later record of the same request stays in the file with duplicate_of set to the earliest enquiry_id and exclusion_reason duplicate.

| Situation | How to record it |
|---|---|
| The same company asks again for the same lane and equipment, with pickup within seven days of the first request, by any channel | Duplicate of the earliest record |
| A reminder or chaser about a request already logged | Duplicate of the earliest record |
| Two people at one company ask for the same move | Duplicate of the earliest record |
| The same company asks for a new lane or new equipment | New RFQ |
| Same lane and equipment, with pickup more than seven days from the first request | New RFQ |
| One request lists several lanes | One RFQ |
| A tender invitation covers many lanes | One RFQ, enquiry_type tender_invitation |
| A revised price or a second option for the same request | Same RFQ; raise quote_count |

The seven day window is our proposed rule. Change it if your lanes need another, and state the window you use beside every report.

## Statuses and the chain rule

| Stage | Counts when | Does not count |
|---|---|---|
| Unique RFQ | enquiry_type is shipper_rfq or tender_invitation and duplicate_of is blank | Carrier and driver applications, supplier pitches, questions about shipments already moving, spam, repeats |
| Qualified RFQ | The request fits a service, lane and equipment you sell and holds enough detail to price: origin, destination, cargo, equipment, and dates or frequency | Lanes or equipment you do not offer, cargo you do not accept, requests still incomplete after one clarification |
| Quoted RFQ | At least one price was sent | Second and later prices for the same RFQ, which only raise quote_count |
| Booked RFQ | The customer confirmed an order for at least one shipment | Tender invitations, lane awards, rate agreements without an order, verbal interest |
| Completed | The first booked shipment was delivered | Cancelled orders |

A later status needs the earlier one. quote_status is set only on qualified RFQs, booking_status only on quoted RFQs and completed_shipment_status only on booked RFQs. The status chain check in the formulas file counts rows that break this rule; it must be 0 before you report a rate.

Statuses describe the position at measurement_cutoff. A row still waiting stays pending, and pending rows count in the denominator but not in the numerator, which is why a young cohort shows provisional rates.

## Tender invitations and load tenders

A tender invitation asks you to bid in a shipper's procurement round. Record it as one RFQ. After an award, booking_status stays pending until the first order for a shipment arrives, and first_booking_date is the date of that order, not the award date.

An EDI load tender is different. The X12 204 message offers a specific shipment to a truckload carrier and the 990 message responds to it, so an accepted load tender is a booking. It usually comes from an existing customer, so record acquisition_source existing_customer.

Report tender invitations as their own segment as well as inside the totals, because their lag and value differ from spot requests.

## Value basis

Choose one value_basis for the whole file and print it beside every contribution figure.

| value_basis | The money fields cover | Use it for |
|---|---|---|
| first_shipment | The first completed shipment from the RFQ's first booking | Monthly marketing reports; it matures soonest |
| rfq_bookings | Every shipment booked against the RFQ by the cutoff, such as a quoted weekly lane | Lane and contract requests |
| account_12m | Every completed shipment from the account in the 12 months after its first booking | Channel budget decisions; it matures after a year |

On account_12m, hold the account's 12 month value on the RFQ that produced its first booking. Later RFQs from the same account take acquisition_source existing_customer and 0.00 in the three money fields, so nothing is counted twice.

## Currency and tax convention

All amounts exclude VAT. revenue is invoiced sell revenue for the shipments in value_basis; a shipment that is delivered but not yet invoiced adds nothing until it is invoiced. carrier_cost is the carrier buy cost for the same shipments.

Leave disbursements out of revenue and cost: duties, import VAT and fees you pay in the customer's name and recharge at cost. The EU VAT Directive also keeps such repayments out of the taxable amount (Article 79(c)), and they are not payment for your service.

variable_cost holds other costs those shipments caused and you did not recharge: payment or factoring fees, cargo insurance bought for the load, per load freight exchange fees, claims paid, and bank and currency charges. Salaries, rent, software and marketing stay out; marketing is measured on the cost side. Enter 0.00 when there are none, never a blank.

Enter every amount in one reporting currency and put its ISO 4217 code in currency. Convert other invoice currencies at the ECB euro reference rate for the invoice date.

The ECB usually publishes these rates around 16:00 CET on working days and says they are for information purposes only, with use for transactions strongly discouraged: they suit reporting, not settling invoices. If your reporting currency is not the euro, name the rate source you use and keep it.

Write amounts with a full stop for decimals, two decimals and no thousands separator. Contribution is a management figure, and it is the same whether your accounts present freight revenue gross or net.

## Cohorts and cutoffs

A cohort is every enquiry created in one calendar month, held in cohort_month. Count every stage for that cohort whenever the later event happened, up to measurement_cutoff, and print the cutoff beside each rate.

Set cutoffs from your own lag. Take the bookings of the last twelve months, sort days_to_booking, and set the booking cutoff at the day by which nine in ten had booked. Until you have that history, read each cohort at 30, 60 and 90 days after the month ends, and label the earlier readings provisional.

Do not mix a cohort rate with a period rate. A period rate divides bookings made in a month by quotes sent in the same month; some of those bookings come from older quotes, so the figure moves when volume changes as well as when conversion does.

Ad platforms count inside their own windows. Google Ads records a conversion after an ad click only within the conversion action's window, 30 days by default and settable from 1 to 90 days depending on the source, and Google Analytics uses a 90 day default lookback for key events other than first visits and first opens. This template credits the source recorded when the enquiry arrived, so a booking on day 70 still counts for its cohort and source.

## Costs

Media cost is what you paid the ad platform for a source in the cohort month, excluding VAT. Fully loaded cost adds agency or freelance fees, tools and staff time at an hourly cost for the same source and month. Match each month's cost to the enquiries created in that month.

Keep the two as separate metrics and never add them or swap them. Media cost metrics apply to paid sources only; for unpaid sources such as organic search, referrals or email to your own list, write not applicable and use fully loaded cost.

## The unavailable rule

A metric whose denominator is zero or missing returns the text unavailable. Do not show 0, 0% or a blank in its place. Print the counts beside it, for example "350.00 EUR media cost, 0 qualified RFQs", so the reader still sees the spend.

Realised contribution has no denominator. It is 0 when no RFQ in the cohort has completed, and unavailable when a completed RFQ lacks revenue, carrier_cost or variable_cost. not applicable is used only for media cost metrics on unpaid sources.

## What to report for each cohort

Report the cohort month, measurement cutoff, value basis and reporting currency first. Then the counts at each stage, carrier and driver applications beside them, each rate with the two counts behind it, media and fully loaded cost per qualified RFQ by source, realised contribution with its margin, and the median days to booking with the number of bookings behind it. Note any rule you changed since the last cohort.

## Changes to the method

When you change a rule, such as the duplicate window, a cutoff or the value basis, recalculate earlier cohorts or mark the break in every report that spans it. We record our own changes to this method on the reference page with their date.
