M³ Tracker
Blog
EN FR

7 min read

How We Track Carriers That Don't Have APIs

M³ Tracker Team

The Canadian LTL market has a dirty secret: most carriers don't offer tracking APIs. Not because they can't build them. They just haven't. Guilbault runs their operation out of Laval with a web portal that works fine for their dispatchers. Transkid has a portal too. Vitran gives you a tracking page. But none of them hand you structured data through an API endpoint you can call programmatically.

So how do you build a unified tracking dashboard when half your carriers don't want to talk to software? You get creative.

The Three-Layer Integration Stack

M³ Tracker uses three distinct methods to pull shipment data, and each one exists because the Canadian freight market forced us to build it. The breakdown, roughly, looks like this: about 30% of carriers offer APIs, another 40% have web portals we can scrape, and the remaining 30% require email-based workflows. Every broker's mix is different.

Layer 1: Direct API Connections

When a carrier offers an API, we use it. Morneau in Montreal provides a REST endpoint that returns JSON with pickup dates, delivery confirmations, terminal scans, and POD documents. Speedy Transport has a similar setup. You send a PRO number, you get back structured data — status history, estimated delivery, current terminal location.

The data fields we extract from API carriers include:

API integrations are the fastest and most reliable method. But they cover maybe a third of the carriers a typical Canadian broker works with. That's not enough.

Layer 2: Headless Browser Scraping

This is where it gets interesting. Portal scraping is more reliable than you'd think — and it's how we cover the largest chunk of carriers.

Take Guilbault as an example. Their tracking portal at guilbault.com accepts a PRO number and returns a status page with pickup info, delivery status, and terminal movements. A human would open a browser, type in the number, and read the screen. We do the same thing, except our "human" is a headless Chromium instance running on a server.

Here's what that looks like technically. We launch a headless browser using Playwright (not Puppeteer — Playwright handles multi-browser contexts better and has more reliable auto-waiting). The browser navigates to the carrier's tracking page, fills in the PRO number field, submits the form, and waits for results to render. Then we extract the data from the DOM using CSS selectors specific to that carrier's page structure.

For Vitran, the page structure is different — they render status events in a table with columns for date, time, location, and status description. For Transkid, it's a different layout again. Each carrier gets its own adapter with its own selectors and parsing logic. There's no shortcut here. Someone has to look at each portal and write the extraction code.

What We Extract From Portals

The data we pull from scraped portals is the same as what we get from APIs — PRO numbers, dates, status events, terminal names. The difference is how we get it. Instead of parsing JSON from an API response, we're reading text content from HTML elements. The end result in your dashboard looks identical either way.

One thing portal scraping gives us that surprises people: terminal locations. When Guilbault shows "Arrived at Winnipeg terminal" on their tracking page, we capture that. When Vitran shows a shipment departed from their Calgary hub, we get the timestamp and location. This kind of granular status history is exactly what brokers need to answer the "where's my freight?" question with specifics, not guesses.

Rate Limiting and Polite Scraping

We take carrier infrastructure seriously. A broker checking Guilbault's portal five times a day for one shipment is no big deal. Software checking it every ten minutes for two hundred shipments is a different story.

Our scraping system enforces several constraints:

The result: our scraping generates less total traffic than a single dispatcher manually checking the portal throughout the day. We're not hammering anyone's servers. We're replacing a human clicking around with a script that does the same thing, politely.

Email-Based Tracking for Carriers Off the Grid

Some carriers have no portal. No API. No website tracking of any kind. Groupe LF operates this way. So do some smaller regional carriers running freight between, say, Sudbury and Thunder Bay, or between Edmonton and the oil sands camps north of Fort McMurray.

For these carriers, we built an email-based status request system. Here's the flow:

  1. You click "Request Update" on a shipment in your M³ Tracker dashboard
  2. We send a professional bilingual email (English and French) to the carrier's dispatcher or operations contact
  3. The email contains four colored buttons: Picked Up (blue), In Transit (amber), Delayed (red), and Delivered (green)
  4. The carrier clicks the appropriate button — no login, no account, no app to install
  5. The status updates in your dashboard instantly

Email-based tracking works surprisingly well for small carriers. The dispatcher sees a clean, simple email. They click one button. Done. It takes five seconds. Most carriers respond within a few hours during business days. Some respond in minutes, especially once they've seen the email format a few times and know what to expect.

Each status button links to a unique token-based URL that expires after seven days. The carrier can also add a note — "delayed due to weather in Timmins" or "will deliver tomorrow AM" — which shows up in your dashboard alongside the status change. No back-and-forth emails needed.

The bilingual aspect matters more than people outside Canada realize. A dispatcher at a Quebec-based carrier gets the email in French. A carrier in Alberta gets it in English. Both see the same four buttons, same layout, same simplicity. We don't ask the carrier to figure out which language they prefer — the email handles both.

What Happens When a Portal Changes

The biggest risk with portal scraping is that a carrier redesigns their website. It happens. Guilbault updates their tracking page, and suddenly our CSS selectors point at nothing. Vitran moves to a new platform, and the form fields have different IDs.

We handle this two ways. First, every scraper runs with error detection — if the expected page structure isn't found, it doesn't silently return empty data. It flags the failure and the shipment gets marked for manual review. Second, we monitor scraper success rates continuously. If Guilbault's scraper drops from 98% success to 40% overnight, we know their portal changed and we update the adapter.

In practice, most carriers update their portals rarely. Once or twice a year at most. And the changes are usually minor — a CSS class name change, a new wrapper div. Fixing a broken scraper typically takes an hour, not a week.

The Unified Dashboard

The whole point of this three-layer approach is that you, the broker, shouldn't have to care how the data was obtained. A shipment tracked via Morneau's API looks the same in your dashboard as one tracked by scraping Guilbault's portal or one updated via email from a small carrier in northern Ontario.

Every shipment shows the same fields: carrier name, PRO number, current status, status history, pickup date, estimated delivery, actual delivery. The four-step progress bar — Booked, Picked Up, In Transit, Delivered — works identically regardless of data source. You can filter, sort, search, and export to CSV without thinking about the plumbing underneath.

Auto-tracked carriers (API and portal) update on their own. Manual carriers get the email workflow. Your dashboard shows both, side by side, in the same format. That's the goal: one screen, all your freight, no portal hopping.

Getting Started

If you're a Canadian freight broker juggling five carrier portals and a stack of email threads, this is what M³ Tracker was built for. We already support Guilbault, Vitran, Morneau, Speedy Transport, Transkid, and more — with new carriers added regularly based on what our users need. Create an account and add your first shipment in under two minutes.

Frequently asked questions

Can you track carriers that don't have a tracking API?

Yes. M³ Tracker uses three approaches: direct API connections for carriers that support them, headless browser scraping for carrier portals (like Guilbault, Vitran, and Transkid), and an email-based status request system with one-click response buttons for carriers with no digital tracking at all.

What data fields does M³ Tracker extract from carrier portals?

For each shipment, we extract the PRO number, pickup date, estimated and actual delivery dates, full status history with timestamps and terminal locations, and proof-of-delivery (POD) when available. All data gets normalized into a consistent format regardless of carrier.

Does portal scraping overload carrier websites?

No. We enforce strict rate limiting (one request at a time per carrier domain), poll only during business hours (7 AM to 7 PM Eastern), and use circuit breakers that back off exponentially when errors occur. Our scraping generates less traffic than a single dispatcher checking the portal manually throughout the day.

How quickly do email-based status updates come through?

It depends on the carrier. The email contains four colored status buttons — the carrier dispatcher clicks one and the update appears in your dashboard within seconds. Most carriers respond within 1-4 hours during business hours. Some respond in minutes.

Ready to automate your tracking?

Join Canadian freight brokers already using M³ Tracker.

Create an account