Run a 3PL RFP by asking each warehouse to price only the fulfillment work, in the same units, against the same operating brief. A combined RFP that also asks for parcel and freight prices mixes two decisions, so the warehouse answers stop being comparable and the choice of warehouse starts to look like a shipping choice.
What should the RFP ask the warehouse to price?
Ask for a pricing schedule with a fixed unit on every line. If one bidder quotes pick and pack per order and another per item, the totals cannot be compared.
| Pricing line | Ask bidders to price per | Where quotes usually diverge |
|---|---|---|
| Receiving | Inbound carton or pallet, unloading stated | Container unloads and special handling left out |
| Storage | Pallet or cubic foot, with the measurement date | Peak space billed at a different rate |
| Pick and pack | Order, plus each additional item | Packaging materials billed separately |
| Returns | Return received and inspected | Restocking fees on a separate rate card |
| Minimums | Per month, with the charges that count toward it | Shortfall billed on top of the minimum |
| Accessorials | Each trigger, with who approves the work | Open-ended project labor at an hourly rate |
What should the service terms require?
Require each bidder to name the event that starts and stops every service clock: receipt closed, order released, carrier handoff. A promise to ship same day means nothing until the RFP defines the start and the stop.
Also require a written exception path: who is told when an order misses its cutoff, through which channel, and by when.
How do you keep bidders on the same footing?
Send every candidate the same brief, pricing schedule and deadline. Share the answer to any clarifying question with all bidders, not only the one who asked. A bidder that prices a different scope has answered a different RFP, and the comparison has to say so.
How do you keep shipping out of the warehouse RFP?
- State in the RFP that parcel and freight are not part of the bid.
- Ask one question: how will this facility operate with carrier accounts that I hold in my own name, including label setup, pickups, billing visibility and claims contacts?
- Ask for the handoff in writing: who prepares shipment data, who books pickups, who opens a transit claim.
- If you want transportation bid, issue a separate request and score it in its own round.
Holding the carrier accounts yourself means the rates question gets answered apart from the warehouse question. The warehouse answer then has to fit those accounts rather than replace them.
How do you score the responses?
Write the weights before the first response arrives. A scorecard drafted after prices are visible tends to reward the lowest number, whatever the execution gaps.
Score four things:
- Execution: how the bidder runs a sample order from your own brief, shown on a walkthrough rather than a slide.
- Complete cost: the total from your pricing schedule, with the sample invoice attached.
- Service and exceptions: the written definitions and escalation path.
- Exit and data: notice period, inventory release, and the format of the final data export.
For the quote comparison itself, see how do I compare 3PL quotes apples to apples. For exit and data terms, see what happens to my data when I switch 3PLs.
If you want an outside check on the scope before it goes out, new3PL is an independent adviser, not a fulfillment operator, and one neutral option for that review.
FAQ
Should shipping go in the same RFP as the warehouse?
No, because a combined response mixes warehouse prices with parcel and freight prices. Send transportation as a separate request if you need one.
Does a small brand need a formal RFP?
It needs the same brief sent to every candidate and written answers back. The document can be short: the brief, the pricing schedule and the scoring weights.
What should every bidder send back?
A completed pricing schedule in your units, a description of each proposed facility's work, a sample invoice built from your order profile, and the exit and data terms. Anything left blank counts as a gap.