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.
| Scope | Allows |
|---|---|
| loads:read | Read your loads, their offers and your Do-Not-Use list. |
| loads:write | Post and edit loads; manage your Do-Not-Use list. |
| loads:cancel | Withdraw loads. |
| loads:assign | Award loads and reject awards. |
| carriers:read | Look up carriers and their verification. |
Integration flow
- Post a load with
POST /loads. UsepriceType: "offers"to receive carrier prices, and optionallyminAllInPrice/maxAllInPricefor your range. - Receive
load_offer.createdon your webhook each time a carrier sends an offer, or pollGET /loads/{id}/offers. Carriers on your Do-Not-Use list can't send offers. - Check the carrier with
GET /carriers/{id}, using thecarrier_idfrom the offer, and run your own compliance checks. - Award the load with
POST /loads/{id}/assign. This generates the Rate Confirmation for the carrier to sign. - If the carrier fails your checks after the award, call
POST /loads/{id}/rejectwith 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.
| Method | Path | Scope | Description |
|---|---|---|---|
| GET | /loads | loads:read | List the loads posted by your account. |
| POST | /loads | loads:write | Post a load. Broker accounts with an active membership. |
| GET | /loads/{id} | loads:read | Get one of your loads. |
| PATCH | /loads/{id} | loads:write | Update a load before a carrier is assigned. |
| POST | /loads/{id}/cancel | loads:cancel | Withdraw a load from the board. |
| GET | /loads/{id}/offers | loads:read | Offers from carriers, with their verification. |
| POST | /loads/{id}/assign | loads:assign | Award the load and generate the Rate Confirmation. |
| POST | /loads/{id}/reject | loads:assign | Reverse an award and reopen the load. |
| GET | /dnu | loads:read | Your Do-Not-Use carrier list. |
| PUT | /dnu | loads:write | Replace your Do-Not-Use list. |
| PATCH | /dnu | loads:write | Add or remove Do-Not-Use entries. |
| GET | /carriers?usdot=&mc= | carriers:read | Look up a carrier by USDOT or MC. |
| GET | /carriers/{id} | carriers:read | A 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.
| Event | Sent when |
|---|---|
| load.created | A load was posted through the API. |
| load.updated | A load changed: edited, awarded, accepted, or signed. |
| load.covered | A load was awarded to a carrier. You can take it down from other boards. |
| load.reopened | An award fell through before the carrier accepted. The load is available again. |
| load.cancelled | A load was withdrawn. |
| load.award_rejected | You rejected an award and the load reopened. |
| load_offer.created | A 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:
| Header | Content |
|---|---|
| x-carrier-connect-event | The event type. |
| x-carrier-connect-delivery | Unique delivery id, the same on every retry. Use it to ignore duplicates. |
| x-carrier-connect-timestamp | Unix time, in seconds, when this attempt was sent. |
| x-carrier-connect-signature-v2 | HMAC-SHA256 (hex) of `timestamp.body`, signed with your secret. |
| x-carrier-connect-signature | Deprecated. 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)." } }| Status | Meaning |
|---|---|
| 400 | The body isn't valid JSON. |
| 401 | Missing, invalid, expired or revoked API key. |
| 403 | The key lacks the scope, or the account can't perform this action. |
| 404 | Not found, or it isn't yours. |
| 409 | The load's current status doesn't allow this action. |
| 422 | Missing or invalid fields. The message says which. |
| 429 | Rate 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.