The 10-second ceiling: why the Carrier Service API crashes checkouts
Native Shopify shipping profiles work for simple parcel weights, but collapse on dynamic multi-pallet LTL freight quotes.
The Carrier Service API invokes an external callback during checkout. If the endpoint exceeds Shopify's rigid 10-second timeout, the connection is aborted and checkout displays 'No shipping options available', crashing conversion.
Physical pallet density: weight limits vs volume cubing
Heavy goods like stone, aggregate, and pavers weigh out before cubing out. A cubic yard of crushed granite reaches 2,700 pounds, maxing out standard liftgates in 10% of a trailer floor.
A calculation engine must calculate palletization density (typically 2,200 lbs per pallet ceiling) to prevent carrier over-weight rejections and unexpected freight re-classification penalties.
Accessorial surcharges: residential delivery and hydraulic liftgates
Freight carriers assume tractor-trailers are unloading at industrial docks. Residential addresses prohibit 53ft trailers and lack forklifts, requiring straight trucks and hydraulic liftgates.
Our rate engine analyzes address strings for commercial keywords versus residential indicators, automatically pricing mandatory liftgate accessorial fees upfront.
import assert from "node:assert/strict";
export interface CartLineItem {
name: string;
sku: string;
quantity: number;
grams: number;
priceCents: number;
properties?: Record<string, string>;
metafields?: {
is_palletized?: boolean;
max_pallet_weight_lbs?: number;
requires_flatbed?: boolean;
};
}
export interface ShippingAddressContext {
countryCode: string;
provinceCode: string;
postalCode: string;
city: string;
addressLine1: string;
isResidential?: boolean;
}
export interface CarrierServiceRateRequest {
originPostalCode: string;
originState: string;
destination: ShippingAddressContext;
items: CartLineItem[];
currency: string;
requestTimestampMs?: number;
}
export interface CarrierServiceRateResponse {
rates: Array<{
service_name: string;
service_code: string;
total_price: number;
currency: string;
description: string;
}>;
executionMetrics: {
totalWeightLbs: number;
palletCount: number;
zoneCode: string;
residentialSurchargeApplied: boolean;
liftgateSurchargeApplied: boolean;
isFallbackRate: boolean;
};
}
const GRAMS_PER_POUND = 453.59237;
const DEFAULT_MAX_PALLET_WEIGHT_LBS = 2200;
const RESIDENTIAL_LIFTGATE_SURCHARGE_CENTS = 8500;
const FLATBED_MOFFETT_SURCHARGE_CENTS = 15000;
const BASE_HANDLING_PER_PALLET_CENTS = 4500;
const FREIGHT_ZONE_RATES_CENTS: Record<string, { baseFirstPalletCents: number; additionalPalletCents: number }> = {
ZONE_LOCAL: { baseFirstPalletCents: 18500, additionalPalletCents: 9500 },
ZONE_REGIONAL: { baseFirstPalletCents: 27500, additionalPalletCents: 14500 },
ZONE_NATIONAL: { baseFirstPalletCents: 42000, additionalPalletCents: 22000 },
ZONE_REMOTE: { baseFirstPalletCents: 65000, additionalPalletCents: 35000 },
};
export function resolveFreightZone(destState: string): string {
const localStates = ["CA", "NV", "AZ"];
const regionalStates = ["OR", "WA", "UT", "ID", "NM", "CO"];
const remoteStates = ["AK", "HI", "ME", "MT", "WY", "ND", "SD"];
if (localStates.includes(destState.toUpperCase())) return "ZONE_LOCAL";
if (regionalStates.includes(destState.toUpperCase())) return "ZONE_REGIONAL";
if (remoteStates.includes(destState.toUpperCase())) return "ZONE_REMOTE";
return "ZONE_NATIONAL";
}
export function isAddressResidential(address: ShippingAddressContext): boolean {
if (address.isResidential !== undefined) return address.isResidential;
const line = `${address.addressLine1} ${address.city}`.toLowerCase();
const commercialSignals = ["suite", "ste", "bldg", "warehouse", "dock", "industrial", "corp", "logistics"];
for (const signal of commercialSignals) {
if (line.includes(signal)) return false;
}
return true;
}
export function calculateFreightRates(
req: CarrierServiceRateRequest,
simulateTimeoutMs: number = 0
): CarrierServiceRateResponse {
if (simulateTimeoutMs > 2500) {
return {
rates: [
{
service_name: "Standard Freight (Estimated - Review at Dispatch)",
service_code: "LTL_FALLBACK_MANUAL_REVIEW",
total_price: 39500,
currency: req.currency || "USD",
description: "Heavy goods freight estimate. Customer service will verify site access before delivery.",
},
],
executionMetrics: {
totalWeightLbs: 0,
palletCount: 1,
zoneCode: "FALLBACK",
residentialSurchargeApplied: false,
liftgateSurchargeApplied: false,
isFallbackRate: true,
},
};
}
let totalGrams = 0;
let liftgateRequested = false;
let flatbedRequired = false;
for (const item of req.items) {
totalGrams += item.grams * item.quantity;
if (item.properties?.["_requires_liftgate"] === "true" || item.properties?.["liftgate"] === "yes") {
liftgateRequested = true;
}
if (item.metafields?.requires_flatbed) {
flatbedRequired = true;
}
}
const totalWeightLbs = Math.round(totalGrams / GRAMS_PER_POUND);
if (totalWeightLbs < 150) {
return {
rates: [
{
service_name: "Standard Ground Parcel (Sample / Small Package)",
service_code: "GROUND_PARCEL",
total_price: 2450,
currency: req.currency || "USD",
description: "Delivered via UPS / FedEx ground parcel.",
},
],
executionMetrics: {
totalWeightLbs,
palletCount: 0,
zoneCode: "PARCEL",
residentialSurchargeApplied: false,
liftgateSurchargeApplied: false,
isFallbackRate: false,
},
};
}
const palletCount = Math.max(1, Math.ceil(totalWeightLbs / DEFAULT_MAX_PALLET_WEIGHT_LBS));
const zoneCode = resolveFreightZone(req.destination.provinceCode);
const zonePricing = FREIGHT_ZONE_RATES_CENTS[zoneCode] || FREIGHT_ZONE_RATES_CENTS.ZONE_NATIONAL;
let baseRateCents = zonePricing.baseFirstPalletCents;
if (palletCount > 1) {
baseRateCents += (palletCount - 1) * zonePricing.additionalPalletCents;
}
baseRateCents += palletCount * BASE_HANDLING_PER_PALLET_CENTS;
const residential = isAddressResidential(req.destination);
let accessorialCents = 0;
const applyLiftgate = residential || liftgateRequested;
if (applyLiftgate) {
accessorialCents += RESIDENTIAL_LIFTGATE_SURCHARGE_CENTS;
}
if (flatbedRequired) {
accessorialCents += FLATBED_MOFFETT_SURCHARGE_CENTS;
}
const standardTotal = baseRateCents + accessorialCents;
const rates: CarrierServiceRateResponse["rates"] = [
{
service_name: `Standard Curbside Freight (${palletCount} Pallet${palletCount > 1 ? "s" : ""})`,
service_code: "LTL_CURBSIDE_FREIGHT",
total_price: standardTotal,
currency: req.currency || "USD",
description: `LTL freight delivery for ${totalWeightLbs} lbs.${applyLiftgate ? " Hydraulic liftgate service included." : ""}`,
},
];
if (zoneCode === "ZONE_REGIONAL" || zoneCode === "ZONE_LOCAL") {
rates.push({
service_name: `Priority Curbside Freight (${palletCount} Pallet${palletCount > 1 ? "s" : ""})`,
service_code: "LTL_PRIORITY_FREIGHT",
total_price: Math.round(standardTotal * 1.35),
currency: req.currency || "USD",
description: "Guaranteed 48-hour transit window with direct carrier dispatch.",
});
}
return {
rates,
executionMetrics: {
totalWeightLbs,
palletCount,
zoneCode,
residentialSurchargeApplied: residential,
liftgateSurchargeApplied: applyLiftgate,
isFallbackRate: false,
},
};
}Carrier Service API JSON payload contract and delivery promises
Shopify requires the callback to emit an array of rates with total_price in integer minor units, persistent service codes, and optional min_delivery_date and max_delivery_date promises.
Emitting delivery date promises in Checkout Extensibility sets realistic commercial delivery expectations and reduces post-order support inquiries.
Platform boundaries: Delivery Customization Functions vs Carrier Service API
Checkout Extensibility Delivery Customization Functions execute in WebAssembly sandboxes to hide, rename, and reorder existing methods. They cannot calculate dynamic rates from scratch because they have zero network access.
Carrier Service API is the sole calculation authority for dynamic rates. Combining both APIs lets Carrier Service compute LTL freight while Functions hide conflicting parcel options.
When this needs an engineer
You do not need a custom freight engine if your products weigh under 70 pounds and ship in standard parcels. You need an engineer when orders exceed parcel limits, when heavy freight must be mathematically split across pallets, and when slow 3PL APIs threaten to freeze checkout.
Review our work in custom application engineering, explore the Online Stone Solutions case study, or inspect our custom Shopify app development services.
