Carrier-Connect Partner API

Connect your TMS to the Carrier-Connect load board. Post your loads, get offers from verified carriers in real time, award the load with a Rate Confirmation, and check any carrier's FMCSA, insurance and identity verification before you book.

Overview

Carrier-Connect is a load board. It connects shippers and brokers with carriers that went through a verification process: operating authority checked against FMCSA, insurance on file, identity checked through Motus, and a manual review of the full document package by our team.

Carrier-Connect does not process freight payments. Prices you send are informational, and payment terms stay between you and the carrier.

Base URL: https://www.carrier-connect.center/api/v1. All requests and responses are JSON. Request bodies use camelCase field names; responses use snake_case.

Authentication

Send your API key in the Authorization header as a Bearer token. Keys are issued by Carrier-Connect; contact us to get one.

Authorization: Bearer cc_live_...

Keys starting with cc_test_ use the sandbox: the same URLs return realistic sample responses, and nothing touches real loads or carriers. Build and test your integration there first, then switch to a cc_live_ key.

Each key has scopes. A request without the required scope returns 403.

ScopeAllows
loads:readRead your loads, their offers and your Do-Not-Use list.
loads:writePost and edit loads; manage your Do-Not-Use list.
loads:cancelWithdraw loads.
loads:assignAward loads and reject awards.
carriers:readLook up carriers and their verification.

Integration flow

  1. Post a load with POST /loads. Use priceType: "offers" to receive carrier prices, and optionally minAllInPrice / maxAllInPrice for your range.
  2. Receive load_offer.created on your webhook each time a carrier sends an offer, or poll GET /loads/{id}/offers. Carriers on your Do-Not-Use list can't send offers.
  3. Check the carrier with GET /carriers/{id}, using the carrier_id from the offer, and run your own compliance checks.
  4. Award the load with POST /loads/{id}/assign. This generates the Rate Confirmation for the carrier to sign.
  5. If the carrier fails your checks after the award, call POST /loads/{id}/reject with a reason code. The load reopens right away and the other valid offers stay available.

Endpoints

Paths are relative to the base URL. The OpenAPI spec has every field, status code and response shape; you can import it into Postman, Insomnia or Swagger.

MethodPathScopeDescription
GET/loadsloads:readList the loads posted by your account.
POST/loadsloads:writePost a load. Broker accounts with an active membership.
GET/loads/{id}loads:readGet one of your loads.
PATCH/loads/{id}loads:writeUpdate a load before a carrier is assigned.
POST/loads/{id}/cancelloads:cancelWithdraw a load from the board.
GET/loads/{id}/offersloads:readOffers from carriers, with their verification.
POST/loads/{id}/assignloads:assignAward the load and generate the Rate Confirmation.
POST/loads/{id}/rejectloads:assignReverse an award and reopen the load.
GET/dnuloads:readYour Do-Not-Use carrier list.
PUT/dnuloads:writeReplace your Do-Not-Use list.
PATCH/dnuloads:writeAdd or remove Do-Not-Use entries.
GET/carriers?usdot=&mc=carriers:readLook up a carrier by USDOT or MC.
GET/carriers/{id}carriers:readA carrier's full verification status.

Reason codes for POST /loads/{id}/reject: CARRIER_NOT_FOUND, IDENTITY_MISMATCH, DO_NOT_USE, LANE_RESTRICTION, INSURANCE_FAIL, AUTHORITY_FAIL, SAFETY_FAIL, DUPLICATE_AWARD, STALE_POSTING, SYSTEM_ERROR.

Examples

Post a load that accepts carrier offers:

curl -X POST https://www.carrier-connect.center/api/v1/loads \
  -H "Authorization: Bearer cc_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "2 sedans, Miami FL to Atlanta GA",
    "originCity": "Miami",
    "originState": "FL",
    "destinationCity": "Atlanta",
    "destinationState": "GA",
    "pickupWindowStart": "2026-10-02",
    "priceType": "offers",
    "maxAllInPrice": 1600
  }'

Award the load to the carrier from an offer:

curl -X POST https://www.carrier-connect.center/api/v1/loads/LOAD_ID/assign \
  -H "Authorization: Bearer cc_test_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "carrierId": "CARRIER_ID_FROM_THE_OFFER",
    "agreedPrice": 1400,
    "pickupLocationName": "Miami Auto Auction",
    "pickupAddress": "1234 NW 36th St, Miami, FL 33142",
    "deliveryLocationName": "Atlanta Dealer Lot",
    "deliveryAddress": "500 Peachtree Industrial Blvd, Atlanta, GA 30341"
  }'

Check a carrier's verification by MC number:

curl "https://www.carrier-connect.center/api/v1/carriers?mc=765432" \
  -H "Authorization: Bearer cc_test_YOUR_KEY"
{
  "data": [
    {
      "id": "4f1c…",
      "company_name": "Acme Transport LLC",
      "usdot_number": "1234567",
      "mc_number": "765432",
      "verification": {
        "overall": "verified",
        "authority": { "status": "verified", "fmcsa_status": "ACTIVE", "last_checked_at": "2026-09-20T14:02:11Z" },
        "insurance": { "status": "verified", "expires_at": "2027-06-30" },
        "motus": { "status": "verified", "motus_status": "PASS", "last_checked_at": "2026-09-20T14:02:15Z" }
      }
    }
  ]
}

verification.overall is verified only after our team approved the carrier's full document package. It changes to expired automatically when a required document, such as insurance, expires.

Webhooks

We send a POST with a JSON body to the URL registered for your account whenever something happens to one of your loads. Webhook URLs and signing secrets are set up by Carrier-Connect together with your API key.

EventSent when
load.createdA load was posted through the API.
load.updatedA load changed: edited, awarded, accepted, or signed.
load.coveredA load was awarded to a carrier. You can take it down from other boards.
load.reopenedAn award fell through before the carrier accepted. The load is available again.
load.cancelledA load was withdrawn.
load.award_rejectedYou rejected an award and the load reopened.
load_offer.createdA carrier sent an offer on one of your loads.

The body is the load, or for load_offer.created the offer with its carrier. Every delivery includes these headers:

HeaderContent
x-carrier-connect-eventThe event type.
x-carrier-connect-deliveryUnique delivery id, the same on every retry. Use it to ignore duplicates.
x-carrier-connect-timestampUnix time, in seconds, when this attempt was sent.
x-carrier-connect-signature-v2HMAC-SHA256 (hex) of `timestamp.body`, signed with your secret.
x-carrier-connect-signatureDeprecated. HMAC-SHA256 of the body only, kept for existing integrations.

Verify the v2 signature against the raw body and reject deliveries older than 5 minutes. Example in Node.js:

import { createHmac, timingSafeEqual } from "node:crypto";

// rawBody must be the exact request body string, before JSON.parse.
export function isValidCarrierConnectWebhook(rawBody, headers, secret) {
  const timestamp = headers["x-carrier-connect-timestamp"];
  const signature = headers["x-carrier-connect-signature-v2"];
  if (!timestamp || !signature) return false;

  // Reject old deliveries so a captured request can't be replayed.
  const age = Math.abs(Date.now() / 1000 - Number(timestamp));
  if (!Number.isFinite(age) || age > 300) return false;

  const expected = createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  const a = Buffer.from(expected, "hex");
  const b = Buffer.from(signature, "hex");
  return a.length === b.length && timingSafeEqual(a, b);
}

Respond with any 2xx status within 8 seconds. If your endpoint fails or times out, we retry up to 7 more times over about 24 hours, with increasing waits. Redirects are not followed, so register the final URL.

Errors and limits

Every error has the same shape:

{ "error": { "message": "This load can no longer be edited (a carrier is already assigned)." } }
StatusMeaning
400The body isn't valid JSON.
401Missing, invalid, expired or revoked API key.
403The key lacks the scope, or the account can't perform this action.
404Not found, or it isn't yours.
409The load's current status doesn't allow this action.
422Missing or invalid fields. The message says which.
429Rate limit exceeded. Wait the seconds in Retry-After.

Each key can make 60 requests per minute and 10,000 per day. If your integration needs more, contact us and we can raise the limit for your key.

Questions about the API? ekaterinasales@carrier-connectcom.com. See also our Terms and Privacy Policy.