Home → Blog

You need to look up a motor carrier by DOT number and wire the result into your app. By the end of this guide you will query FreightPulse for a carrier lookup, read the response safely in PHP, and return just the fields your system needs, without guessing at fields or endpoints.

What you are building

This walkthrough implements a DOT-based carrier lookup using FreightPulse. You will authenticate with an X-API-Key header, call the carriers endpoint with a query string, parse the standardized envelope, and render carrier identity and safety fields. A complete PHP implementation is provided, with a lightweight JavaScript example for front-end or Node scripts.

Illustration: How to Get Carrier Lookup

API facts you must know before writing code

Quick test with cURL

Run this from your shell to verify connectivity and your key handling. Replace only YOUR_API_KEY with your key if you have one; anonymous calls still work within the guest limit.

curl -H "X-API-Key: YOUR_API_KEY" "https://freightpulsehq.com/api/v1/carriers?q=54283"

Official sample response for DOT 54283

This is the official fixture you should use to validate your parser. Notice the top-level success boolean and data object, and the results array containing one carrier match.

{
"success": true,
"data": {
"type": "trucking",
"query": "54283",
"results": [
{
"dot_number": 54283,
"legal_name": "SWIFT TRANSPORTATION COMPANY OF ARIZONA LLC",
"status": "active",
"safety_rating": "S",
"drivers": 12883,
"address": {
"city": "Phoenix",
"state": "AZ",
"country": "US"
}
}
]
}
}

Fields you are likely to use:

PHP implementation: end-to-end carrier lookup

The following PHP script calls the carriers endpoint, validates the envelope, and returns normalized output. It is designed to be dropped into a controller action or a small CLI tool. It handles missing keys, HTTP errors, JSON decoding errors, and the possibility of multiple results in the results array.

PHP: minimal client with robust checks

<?php
declare(strict_types=1);

/**
* Carrier lookup by DOT using FreightPulse.
* Requirements:
* - PHP 7.4+ (json extension enabled).
* - Network access to https://freightpulsehq.com/.
*
* Notes:
* - Guests without a key are limited to 100 requests/day per IP.
* - Set $apiKey to YOUR_API_KEY to authenticate; leave empty to operate as a guest.
*/

function freightpulse_carrier_lookup(string $dot, string $apiKey = ''): array
{
$url = 'https://freightpulsehq.com/api/v1/carriers?q=' . rawurlencode($dot);

$ch = curl_init($url);
if ($ch === false) {
throw new RuntimeException('Failed to initialize cURL');
}

$headers = [];
// Add X-API-Key header whether empty or not; the API accepts guest calls without a key.
$headers[] = 'X-API-Key: ' . ($apiKey !== '' ? $apiKey : 'YOUR_API_KEY');

curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => $headers,
]);

$raw = curl_exec($ch);
if ($raw === false) {
$err = curl_error($ch);
curl_close($ch);
throw new RuntimeException('cURL error: ' . $err);
}

$httpStatus = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($httpStatus < 200 || $httpStatus >= 300) {
throw new RuntimeException('HTTP error status: ' . $httpStatus . ' Body: ' . $raw);
}

$json = json_decode($raw, true);
if (!is_array($json)) {
throw new RuntimeException('Invalid JSON response');
}

if (!array_key_exists('success', $json) || $json['success'] !== true) {
throw new RuntimeException('API indicated failure or missing success flag');
}

if (!array_key_exists('data', $json) || !is_array($json['data'])) {
throw new RuntimeException('Malformed envelope: missing data');
}

$data = $json['data'];
$results = $data['results'] ?? [];
if (!is_array($results) || count($results) === 0) {
return [
'query' => strval($data['query'] ?? $dot),
'matches' => 0,
'carriers' => [],
];
}

// Normalize each result to a flat structure your app can render quickly.
$carriers = [];
foreach ($results as $r) {
$carriers[] = [
'dot_number' => $r['dot_number'] ?? null,
'legal_name' => $r['legal_name'] ?? null,
'status' => $r['status'] ?? null,
'safety_rating' => $r['safety_rating'] ?? null,
'drivers' => $r['drivers'] ?? null,
'city' => $r['address']['city'] ?? null,
'state' => $r['address']['state'] ?? null,
'country' => $r['address']['country'] ?? null,
];
}

return [
'query' => strval($data['query'] ?? $dot),
'matches' => count($carriers),
'type' => $data['type'] ?? null,
'carriers' => $carriers,
];
}

// Example usage: php carrier_lookup.php 54283
if (PHP_SAPI === 'cli' && basename(__FILE__) === basename($_SERVER['argv'][0] ?? '')) {
$dot = $_SERVER['argv'][1] ?? '';
if ($dot === '') {
fwrite(STDERR, "Usage: php " . basename(__FILE__) . " DOT_NUMBER\n");
exit(2);
}

// Provide YOUR_API_KEY to raise limits and access authenticated features.
$apiKey = getenv('FREIGHTPULSE_API_KEY') ?: '';

try {
$result = freightpulse_carrier_lookup($dot, $apiKey);
// Print as JSON for pipeline compatibility.
fwrite(STDOUT, json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n");
exit(0);
} catch (Throwable $e) {
fwrite(STDERR, "Error: " . $e->getMessage() . "\n");
exit(1);
}
}

JavaScript example (Node or browser fetch)

This snippet demonstrates how to fetch the same endpoint and read the key fields. In a browser, ensure CORS is allowed for your integration; otherwise call from your backend.

async function lookupCarrier(dot, apiKey) {
const url = 'https://freightpulsehq.com/api/v1/carriers?q=' + encodeURIComponent(dot);
const res = await fetch(url, {
headers: {
'X-API-Key': apiKey && apiKey.length > 0 ? apiKey : 'YOUR_API_KEY'
},
redirect: 'follow'
});

if (!res.ok) {
throw new Error('HTTP ' + res.status + ' from carriers endpoint');
}

const json = await res.json();

if (!json || json.success !== true || !json.data) {
throw new Error('Unexpected envelope or API failure');
}

const results = Array.isArray(json.data.results) ? json.data.results : [];
return results.map(r => ({
dot_number: r.dot_number,
legal_name: r.legal_name,
status: r.status,
safety_rating: r.safety_rating,
drivers: r.drivers,
city: r.address && r.address.city,
state: r.address && r.address.state,
country: r.address && r.address.country
}));
}

// Example usage:
lookupCarrier('54283', '')
.then(list => console.log(list))
.catch(err => console.error(err));

Implementation notes that save time

Testing and validation checklist

Integrating into your stack

In a monolith or service-oriented architecture, isolate the FreightPulse call in a gateway module. Expose a function getCarrierByDot(dot) that returns your normalized shape. Surround the gateway with retries and circuit-breaking to prevent cascading failures if the upstream network blips.

When persisting, store both the original JSON and your normalized projection. The original blob lets you reprocess fields if your schema evolves. Tag each record with your fetched_at timestamp in UTC and the query string you used (data.query) for traceability.

Field mapping reference

Common pitfalls and how to avoid them

Where to go next

For parameter nuances and broader endpoints, read the official Documentation. Use a real API key to raise limits and build a stable integration in staging, then production.

FAQ

Do I need an API key to test?
Not strictly. Guests without a key can make up to 100 requests per day per IP. Add X-API-Key: YOUR_API_KEY to move beyond that and for production use.

Is the response always an array in data.results?
Yes. Treat results as an array and iterate, even if you expect a single DOT match.

Can I treat congestion metrics as live port wait times?
No. FreightPulse congestion uses IMF PortWatch, lagged about 6–7 days (7-day average vs 90-day baseline). It is not live AIS.

Can I quote freight rates from this endpoint?
No. This lookup is for carrier data. Do not quote a freight-rates USD fare as today’s price based on this response.

How should I cache lookups?
Cache by DOT for hours to a day, depending on how frequently you need updates. Always validate success and stale data before serving from cache.

Ready to integrate this lookup into your app? Create your account in minutes and get an API key here: Register. Then keep this guide open and ship the PHP integration in one sitting.