What the Purolator API actually gives you
Purolator is the Canada-only carrier that competes with Canada Post for domestic ground volume. If you ship inside Canada, B2B pallets, B2C parcels, or anything in between, Purolator is on your shortlist. The Purolator API is how your ERP talks to that carrier without anyone re-keying a shipment into Purolator's web portal.
The API surfaces four operations that matter for Odoo: rate quoting (what will this shipment cost?), label creation (give me a PDF of the shipping label and tracking number), pickup scheduling (send a driver to my warehouse tomorrow at 2 pm), and tracking queries (where is shipment 329028123 right now?). All four are SOAP endpoints under the legacy Shipping Web Services v1, with REST equivalents rolling out since 2024 for Estimate and Ship.
This guide is written by Octura Solutions, an Official Odoo Ready Partner that has shipped Purolator integrations for Canadian wholesalers, manufacturers, and DTC brands across Odoo 15 through 19. The patterns below come from those deployments, not from Purolator's developer-portal samples (which are correct but spartan and don't tell you what to wire into the Odoo side).
Why integrate Purolator into Odoo (not just print labels manually)
Small shippers can survive on Purolator's web portal: log in, type the destination, click "create label", print, ship, done. That breaks at three thresholds:
- 20 shipments a day. Re-keying every order takes ~3 minutes per label including the address copy-paste, which is one full-time hour per day burned. At that point a one-time API integration pays for itself in three weeks of staff cost.
- Multi-carrier rate shopping. The minute you want "cheapest of Purolator / FedEx / UPS for each shipment", manual quoting is impossible, the warehouse staff doesn't have time to check three portals per order. The only viable answer is an automated rate query at order-confirmation time.
- B2B retail compliance. Loblaws, Sobeys, Walmart Canada, Costco Canada all require an SSCC-tagged pallet label that ties back to your EDI 856 Advance Ship Notice. The Purolator portal doesn't emit SSCC in the right format, the API does (with the right parameters).
Below those thresholds, manual portal use is fine. Above, the integration cost (typically C$8K-C$15K for a Purolator-only setup, C$18K-C$30K when bundled with FedEx + UPS rate shopping) pays back in 2-4 months of saved labour and prevented compliance fines.
Setup: from production credentials to the first Odoo label
The setup runs in three phases that overlap with each other.
Phase 1: get production credentials from Purolator
Apply for API access via your Purolator account manager (not the developer portal, the form there only issues sandbox keys). You'll need to send them: your Billing Account Number (BAN), the volume forecast for year 1, and the integration vendor name (Octura, in our deployments). Approval takes 5-10 business days and yields a Production Key + Production Password pair scoped to that BAN. The sandbox keys arrive within a day.
Phase 2: configure the Odoo carrier record
In Odoo, create a delivery.carrier record of provider type "Purolator" (you may need a small custom provider extension; the built-in Odoo carrier providers cover FedEx, UPS, DHL, USPS, Canada Post, and a few EU carriers, but not Purolator natively). The record holds the Production Key, BAN, default service type (Purolator Ground is standard for B2B; Purolator Express for B2C), and the originator address that prints as "ship from" on every label.
Phase 3: wire the API calls into the order-to-ship workflow
Three hooks land in the existing Odoo workflow:
- At order confirmation: a rate-quote call returns the shipping cost, which lands on the sales order as the shipping line so the customer is invoiced the real-time number, not a static rate-table guess.
- At stock-picking validation: a label-create call returns the PDF + tracking number, attached to the picking record. The warehouse prints from the picking, no portal login.
- Hourly cron: a tracking-query call pulls live events for every shipment whose status isn't "Delivered" yet. The events post to the sales-order chatter so the CSR sees them inline.
The full order-to-tracking flow once integrated
Once the three hooks are wired, here's what happens on a typical Canadian B2B shipment:
- Step 1, sales order confirmation. Customer places a 40 kg pallet order from Toronto to Halifax. Odoo calls Purolator's Estimate endpoint with the dims + weight + destination. Purolator returns C$87.50 for Purolator Ground (3-day) and C$148 for Purolator Express (next-day). Odoo writes both rates to the sales order, the customer-facing portal picks the one the customer chose at checkout.
- Step 2, warehouse picking + label. Warehouse confirms the picking is complete in Odoo. A button on the picking record calls Purolator's Ship endpoint with the line-item weights and dims. Purolator returns a PDF label + tracking number (e.g., 329028123). The label prints to the warehouse zebra; the tracking number lands on the picking record.
- Step 3, tracking notification to customer. A second post-Ship hook posts the tracking number into the sales-order chatter and triggers an Odoo email template with the Purolator tracking URL. Customer gets the email within 30 seconds of the label being printed.
- Step 4, live tracking updates. Hourly cron pulls Purolator events for the tracking number. "Picked up Toronto 4:15 pm", "In transit Montreal 11:02 pm", "Out for delivery Halifax 7:30 am", "Delivered 11:14 am". Each event posts to the order chatter. The CSR never has to log into the Purolator portal to answer "where's my shipment".
- Step 5, reconciliation. End of week, Odoo pulls a Purolator invoice report (separate endpoint) and reconciles the per-shipment charges against the rate quotes from Step 1. Variances of more than 5% flag for AP review, typically caused by a weight re-classification on Purolator's end (the warehouse said 38 kg, the Purolator scale read 41 kg, you get charged for 41).
Five gotchas we have hit in production Purolator + Odoo deployments
1. Sandbox addresses are not validated the same way as production. A Toronto postal code that works in sandbox can fail in production with "Address not serviceable". Always do a 5-shipment production smoke test before going live.
2. Service-area validation is asymmetric. Purolator Ground reaches every Canadian postal code, but Purolator Express reaches roughly 90%. The remote-area surcharge surfaces in the rate quote, but only if you call the right endpoint, the "Express Cheque" service skips that check and your warehouse gets the surcharge invoice three weeks later.
3. The SOAP API has a 30-second timeout that the REST API does not. If you batch-quote 50 shipments in one call on SOAP, you'll time out. Either chunk to 10-per-call or migrate to the REST Estimate endpoint, which handles batches up to 100.
4. Pickup scheduling is per-account, not per-shipment. Calling SchedulePickup once a day for "all the labels generated since 8 am" works; calling it per-label creates duplicate pickup records and triggers Purolator's anti-abuse rate limiter.
5. Tracking events are not real-time. Purolator's tracking API updates roughly every 30-60 minutes, not on every barcode scan. If your CSR or customer needs sub-minute granularity, you need a different carrier or a sub-account on Purolator's enterprise tier (which costs more).
Want help wiring this up?
Octura builds Purolator integrations as part of broader Odoo shipping setups, single-carrier (Purolator only, typical Canadian SMB), or multi-carrier rate-shopping (Purolator + FedEx + UPS + Canada Post, typical cross-border DTC). Typical engagement is 2-4 weeks from kickoff to first label printed in production. Pair it with our EDI integration guide if you ship to Canadian retailers, the SSCC label coming out of Purolator is what feeds your EDI 856 Advance Ship Notice.
Book a free 30-min Purolator + Odoo reviewFrequently Asked Questions
The questions readers ask us most often on this topic.
What is the Purolator API?
A set of SOAP and REST endpoints that let your ERP request shipping rates, create labels, schedule pickups, and pull tracking events from Purolator without anyone logging into the carrier portal. The legacy Shipping Web Services v1 is SOAP; the newer Estimate and Ship endpoints are REST and rolled out gradually since 2024.
What is a Purolator Production Key?
A Production Key is the credential pair (Production Key + Production Password) Purolator issues to your business after the production-access application. You also get a Development Key for testing against the Purolator sandbox before live traffic. Both are scoped to a specific Billing Account Number (BAN) and required by every API call.
How does Purolator compare to FedEx, UPS, DHL, and Canada Post?
Purolator dominates inter-Canadian B2B ground (faster than Canada Post Expedited, cheaper than UPS Canada for domestic). FedEx and UPS win on cross-border to the US. DHL is the international choice. A serious Canadian Odoo shop usually integrates two or three of these, Purolator for domestic, plus one cross-border carrier.
What is a PWS connector for Odoo?
PWS stands for "Purolator Web Services" connector, the catch-all name for any Odoo module that wraps the Purolator API. The Odoo Apps Store lists a few; we typically build a thin custom module instead because the off-the-shelf ones lag the API and don't support the SSCC + Estimate-REST combo well.
Does Odoo support Purolator natively?
No, the native delivery providers in Odoo cover FedEx, UPS, DHL, USPS, Canada Post, and a few EU carriers but not Purolator. A small custom delivery.carrier provider extension wraps the Purolator API and slots into Odoo's standard sales-order to picking to invoice workflow.
How long does a Purolator + Odoo integration take to build?
For a single-carrier Purolator-only setup with rate quoting, labels, pickup, and tracking, 2 to 4 weeks from kickoff to first production label. For multi-carrier rate shopping (Purolator + FedEx + UPS + Canada Post), 4 to 8 weeks. Most of the time goes into mapping carrier services to Odoo product types and to the in-line testing against Purolator's production sandbox.
How much does a Purolator + Odoo integration cost?
Typical fixed-price engagement: C$8K to C$15K for Purolator-only, C$18K to C$30K when bundled with FedEx, UPS, and Canada Post rate shopping. Payback is 2 to 4 months at 20+ shipments/day from the saved labour of not re-keying every label into the Purolator portal.
Can Purolator print SSCC labels for B2B retail compliance?
Yes, the Ship endpoint accepts an SSCC payload field that prints the 18-digit pallet-level barcode on the label. This is what ties the physical pallet back to the EDI 856 Advance Ship Notice that Loblaws, Sobeys, Walmart Canada, and Costco Canada all require for B2B receiving. If you ship to Canadian retailers, you need both Purolator and an EDI connector working together.
How does multi-carrier rate shopping work in Odoo?
A small custom module on top of Odoo calls Purolator + FedEx + UPS + Canada Post APIs in parallel for each shipment at order confirmation. The cheapest (or fastest, depending on the customer's checkout choice) wins, lands on the sales order as the shipping line, and the rest of the workflow proceeds with the winning carrier. Native Odoo doesn't rate-shop across carriers, you bolt that logic on.
Does Octura build Purolator integrations?
Yes. We build Purolator + Odoo integrations as part of broader Canadian shipping setups, including the multi-carrier rate-shopping variant. Engagements are fixed-price after a 1 to 2 day discovery, typical timeline 2 to 8 weeks depending on scope.