TMS integrations

Cover more Mexico and Canada loads. Stop posting them by hand.

Works with McLeod, Turvo, Tai and Revenova, or any TMS through our API.

  • Loads that match your rules post straight from your TMS.
  • Do-not-use carriers never see your freight.
  • Bids come back to your TMS as new records.
Get started
How it works

Your reps cover freight. The connection does the posting.

Which TMS do you run?

The walkthrough below switches to your TMS.

For IT: access and data scope

Example carriers, loads and rates.

Your loads reach carriers beyond your own list

2,350+
carriers on the marketplace
220,000+
trucks behind them
8 of the top 10
freight brokerages on the Transport Topics 2026 list use Cargado
“Cargado Market Rates helps us quote fast, and that’s when you win it. Customers ask for a rate at 11, and by 11:30 they have it.”
Patty Hinojosa Patty HinojosaVP of Mexico Sales and Operations CargoQuotes
Read the CargoQuotes story
Price where you already work Market Rates API Excel Add-In =CARGADO.RATE_HISTORY_P50(A2, B2, C2, D2)
For your IT team

A small lift for IT. You stay in control.

What leaves your TMS

Nothing reaches a carrier until your rules post it.

  1. You choose the filter

    Filter loads in the integration layer before they reach Cargado, or filter them in Cargado.

  2. Synced is not posted

    A synced load stays private until your posting rules or your reps put it on the board.

  3. Deleted on request

    Anything never posted or shared is deleted when you ask.

Access

One API-only user. Never admin.

  • No UI seat and no admin rights, in sandbox or production.
  • Scoped to the objects the integration needs, so you can audit everything it does.
What we write

New records. Never edits.

  • Bids come back as carrier quotes. Live on McLeod, Tai, Turvo and Revenova.
  • Prefer to start read-only? Turn on write-back later.
Who runs it

Cargado builds, hosts and runs it

  • Queues and flow control
  • Dead-letter queues
  • Change data capture
  • Backfills
  • Vaulted secrets
  • Retries with back-off
  • Health view you can check

From kickoff to live

Included with your Cargado subscription.

  1. 1Kickoff

    A 30-minute call on your TMS, lanes and how reps post today.

    Ops + IT
  2. 2IT grants access

    Takes minutes. On Revenova, under 30 minutes for your Salesforce admin.

    IT, once
  3. 3Ops maps and approves

    Statuses, trailer types, coverage owners and posting rules, tested in a sandbox. About a week, depending on how fast your team answers.

    Ops
  4. 4Go live

    Start with your Mexico or Canada lanes. Add more later.

    Ops turns it on

On the public API? Your engineers build your side against our sandbox and docs.

Deep dive · Field mapping and API

Mapped once at setup. Your TMS stays the source of truth.

McLeod integration

Built, hosted and run by Cargado Bids write back as new records You call the API. We give you a sandbox.

01What syncs, in each direction

Into Cargado, from McLeod

  • Carriers and their status with you: active, needs review or do not use, and whether they are onboarded.
  • Loads and every status change.
  • Load details that make a posting bookable: stops, appointment windows, equipment, crossing and reference numbers.
  • Target rate and max buy, which your posting rules can use.
  • Who covers each load, so postings are assigned to the right rep or team.

Back to McLeod

Back to your system

  • Bids and the carrier behind each one, as new records.
  • Nothing edited. Your existing records stay as they are.
  • Bid events by webhook: submitted, accepted, rejected, revoked, closed, countered, and the counter outcomes.
  • Your offer ID on each bid, stored with POST /bids/update.
  • Market rates: a Low, Mid and High band (25th, 50th and 75th percentile) with a confidence label.

02Field mapping

Every connection fills the same Cargado load model. We map your McLeod fields to it during setup.

Field names from the load sync API. Money is in the smallest currency unit, so $4,125.00 is 412500.

On your loadCargado fieldNotes
Synced to Cargado
Origin and destinationstops[]PICKUP first, DELIVERY last, with each stop’s time zone. Up to 64 stops.
Border crossingborderCrossings[]For example LAREDO_INTL_BRIDGE. If your TMS has none, the matching lane fills it in.
EquipmenttrailerRequirementsFor example DRY_VAN_53 or REEFER.
Pickup and delivery windowsstops[].appointmentA window, an exact time, first come first served, or to be set.
Reference numbersreferenceNumbers[]PO #, BOL # or PRO #, on the load and on each stop.
RatetargetRate, maxBuyGuides your team and can drive posting rules.
Load and customer IDsexternalId, externalCustomerIdNever shown outside your organization.
StatusstatusON_HOLD AVAILABLE ASSIGNED BOOKED CANCELLED COMPLETED
Back from Cargado
Bid amountbid.rateDetailsA total plus line items: all-in, or the Mexico leg, crossing fee and U.S. leg.
CarriercarrierName, DOT, MC, RFC, CVOR, NIR, NSC, SCAC, contact, and your TMS’s carrier ID.
Bid statusbid.statusACCEPTED, REJECTED, COUNTERED and others.

McLeod: equipment types, status codes and deduct codes are matched once, during setup. Charge codes such as DET carry over on the carrier’s price.

Turvo: each charge line keeps its Turvo line item ID, so prices reconcile line by line.

03Which loads sync and post

  • Pick your scope: sync everything and filter in Cargado, drop non-cross-border loads in the integration layer, or send only cross-border loads yourself.
  • Border commercial zones such as Laredo, El Paso and San Diego are geofenced.
  • An optional “Post to Cargado” field gives load-by-load control.
  • Nothing posts by default. A load posts when it is available and matches a rule your team sets.
  • Fields set by your TMS show as “Set in TMS” in Cargado, so an edit in the app can’t overwrite them.

04Carrier status and takedown

  • DO_NOT_DISPATCHNever sees your freight and can’t be assigned to it.
  • NEEDS_REVIEWReviewed by your team before being assigned.
  • ACTIVECan be assigned the moment a load posts.
  • NEEDS_TO_ONBOARDGets an onboarding link on its first match.

The posting comes down when you accept a bid on Cargado, the load is assigned, booked or canceled in your TMS, or it is no longer eligible (for example LTL).

Running your own TMS?

05Access, sandbox and endpoints

Productionhttps://api.cargado.com
Sandboxhttps://api.sandbox.cargado.com, with a broker and a carrier test organization. No real freight posts.
AuthenticationAn Api-Key header, one key for production and one for the sandbox.
WebhooksSigned to the Standard Webhooks spec. After a secret rotation, the old secret works for 24 hours.
POST /loads/syncCreate or update a load and its status.
POST /carrier-relationships/upsertCarrier statuses from your TMS, including do not use.
POST /rates/historyMarket Rates for up to 64 lanes per request. Metered.
POST /bids/updateStore your TMS offer ID on a bid.
POST /webhooks/endpoint/registerRegister an endpoint for bid events.

06API samples

POST/loads/syncCreates the load, or updates it if the externalId exists
Request
POST https://api.cargado.com/loads/sync
Api-Key: <API Key>
Content-Type: application/json

{
  "load": {
    "externalId": "TMS232423",
    "externalCustomerId": "CUST-1042",
    "status": "AVAILABLE",
    "referenceNumbers": [{ "label": "PO #", "value": "45-88120" }],
    "commodities": [{
      "name": "Auto parts",
      "weight": { "type": "APPROXIMATE", "value": 42000, "unit": "POUNDS" },
      "hazmatDetails": { "isHazmat": false }
    }],
    "trailerRequirements": { "allowedTypes": ["DRY_VAN_53"] },
    "carrierRequirements": { "ctpatCertified": true },
    "driverRequirements": {},
    "targetRate": { "currencyCode": "USD", "amount": 412500 },
    "stops": [
      {
        "type": "PICKUP",
        "externalId": "STOP-1",
        "location": {
          "place": { "type": "ADDRESS", "city": "Monterrey", "state": "NLE", "countryCode": "MX" },
          "timezone": "America/Monterrey"
        },
        "appointment": {
          "type": "SET_APPOINTMENT_WINDOW",
          "windowStartTime": "2026-10-05T08:00:00",
          "windowEndTime": "2026-10-05T14:00:00"
        }
      },
      {
        "type": "DELIVERY",
        "externalId": "STOP-2",
        "location": {
          "place": { "type": "ADDRESS", "city": "Chattanooga", "state": "TN", "countryCode": "US" },
          "timezone": "America/New_York"
        },
        "appointment": {
          "type": "SET_APPOINTMENT_WINDOW",
          "windowStartTime": "2026-10-08T06:00:00",
          "windowEndTime": "2026-10-08T14:00:00"
        }
      }
    ],
    "borderCrossings": [
      { "type": "BORDER_CROSSING", "externalId": "XING-1", "usMxBorderCrossing": "LAREDO_INTL_BRIDGE" }
    ]
  }
}
Response 200, abridged
{
  "load": {
    "id": "load_6e4cf1d1-b776-4401-a326-e43df6107e17",
    "externalId": "TMS232423",
    "externalCustomerId": "CUST-1042",
    "status": "AVAILABLE",
    "trailerRequirements": { "allowedTypes": ["DRY_VAN_53"] },
    "stops": [ /* pickup, delivery */ ]
  }
}

// Synced loads do not post on their own.
// A load posts when it matches a posting
// rule you set in Cargado.
//
// Takedown: send status BOOKED or
// CANCELLED, or set assignedCarrier.
// Sending assignedCarrier: null cancels
// the booking in Cargado.
Field names and enums from the Cargado OpenAPI 3.1 spec (Sync a load). The request is an example we assembled from that schema; the docs do not publish one.
POST/rates/historyp25 = Low · p50 = Mid · p75 = High, in cents
Request
POST https://api.cargado.com/rates/history
Api-Key: <API Key>
Content-Type: application/json

{
  "requests": [
    {
      "stops": [
        {
          "type": "PICKUP",
          "placeDetails": {
            "place": {
              "type": "CITY",
              "city": "Monterrey",
              "state": "MX_NLE",
              "country": "MX"
            }
          }
        },
        {
          "type": "BORDER_CROSSING",
          "usMxBorderCrossing": "LAREDO_INTL_BRIDGE"
        },
        {
          "type": "DELIVERY",
          "placeDetails": {
            "place": {
              "type": "CITY",
              "city": "Chicago",
              "state": "US_IL",
              "country": "US"
            }
          }
        }
      ],
      "trailerRequirements": {
        "allowedTypes": ["DRY_VAN"]
      }
    }
  ]
}
Response 200, abridged
{
  "results": [
    {
      "type": "DATA",
      "id": "rhl_9bb338d8-dd63-4441-95b5-ef7e9d890bb2",
      "rateHistory": {
        "pricingLane": {
          "trailerCategory": "DRY_VAN",
          "usMxBorderCrossing": "LAREDO_INTL_BRIDGE"
        },
        "currencyCode": "USD",
        "suggestedRates": [
          {
            "dayRange": { "start": "2025-06-24", "end": "2025-06-30" },
            "amountDistribution": {
              "p25": 364321,  // Low
              "p50": 386075,  // Mid
              "p75": 409126   // High
            },
            "marginOfError": 7004,
            "relativeMarginOfError": 0.02,
            "confidenceScore": 94,
            "confidence": "STRONG"
          }
          /* one entry per week, up to 12 weeks */
        ],
        "routeMiles": 1513.56
      }
    }
  ]
}
Copied from the Look up the rate for freight guide (values from its 2025 example). Confidence is STRONG, MEDIUM or LOWER. Leave out the crossing and Cargado picks the recommended one.
POST/carrier-relationships/upsertDo-not-use carriers never see your freight
Request
POST https://api.cargado.com/carrier-relationships/upsert
Api-Key: <API Key>
Content-Type: application/json

{
  "carrierRelationships": [
    {
      "carrier": {
        "dotNumber": "1234567",
        "mcNumber": "2342342"
      },
      "status": "ACTIVE",
      "onboardingStatus": "ONBOARDED"
    },
    {
      "carrier": {
        "rfcNumber": "012345678912"
      },
      "status": "DO_NOT_DISPATCH",
      "onboardingStatus": "ONBOARDED"
    }
  ]
}
What it does
// Returns the relationships in the same
// order and length as the input.
// If a carrier is not found, its
// relationship comes back as null.
//
// status:           ACTIVE | NEEDS_REVIEW
//                   | DO_NOT_DISPATCH
// onboardingStatus: ONBOARDED
//                   | NEEDS_TO_ONBOARD
//
// Optional: carrierExternalId, your ID
// for the carrier in your TMS.
Copied from the Manage carrier relationships guide.
WEBHOOKbid.acceptedShapePosted to your endpoint, signed. Placeholder values, not a runnable request.
Shape, placeholder values
POST https://your-endpoint.example.com/cargado
webhook-id: <delivery id>
webhook-timestamp: <timestamp>
webhook-signature: <signature>

{
  "eventId": "…",
  "actorId": "usr_…",
  "type": "bid.accepted",
  "timestamp": "…",
  "data": {
    "bid": {
      "id": "bid_…",
      "status": "ACCEPTED",
      "externalId": null,
      "rateDetails": {
        "type": "ItemizedBid",
        "totalAmount": { "currencyCode": "USD", "amount": 420000 },
        "lineItems": [ /* AllIn, CountryLeg, BorderCrossing */ ]
      }
    },
    "posting": { "id": "post_…", "targetRate": …, "maxBuy": …, "reservePrice": … },
    "freight": { "externalId": "TMS232423", … },
    "carrier": {
      "displayName": "Los Fletes Hermanos",
      "dotNumber": "…", "mcNumber": "…", "rfcNumber": "…",
      "externalId": "…"
    }
  }
}
Handling it
// Verify the signature against the RAW
// body before parsing. Reject timestamps
// outside a few minutes.
//
// Dedupe on eventId: a retry can deliver
// the same event twice.
//
// Other types: bid.submitted, bid.rejected,
// bid.revoked, bid.closed, bid.countered,
// bid.counter_accepted,
// bid.counter_revoked,
// bid.counter_rejected
Shape from the Bid events reference and the Webhooks guide. Values are placeholders; the docs do not publish a full example.

Read the API docs

Questions brokers ask

Get started
Which TMSs are live?
McLeod, Turvo, Tai and Revenova. Or connect your own TMS through the Cargado public API.
What does it cost to integrate?
There’s no fee. It’s included with a Cargado subscription, and we build, host and run it.
Do all my loads post to the marketplace?
No. Only loads that match your rules post, and your team sets the rules.
Who sees my freight?
Carriers on the Cargado marketplace, except anyone marked do-not-use in your TMS.
What happens when a load is covered?
The posting comes down, whether you covered it on Cargado or with your own team.
Where do the market rates come from?
Real carrier bids on Cargado. Each lane gets a Low, Mid and High band with a confidence label.