FedEx Rate API Response Mapping
This reference guide describes how the FedEx Rate API response is transformed into the internal ShippingRate type using the Adapter pattern.
Official Documentation
- FedEx Rates and Transit Times API - Main API overview
- FedEx Rate API Documentation - Detailed endpoint documentation
- FedEx Developer Portal - Developer home
Response Overview
The FedEx Rate API returns multiple services in output.rateReplyDetails[]. Each service contains multiple rate types (ACCOUNT, LIST, PREFERRED_INCENTIVE, PREFERRED_CURRENCY). Use the ACCOUNT rate type as the primary rate.
Field Mapping
| ShippingRate Field | FedEx Response Path | Notes |
|---|---|---|
id | Generated | fedex-${serviceType}-${timestamp} |
carrier | Constant | 'FedEx' |
serviceCode | serviceDescription.code | e.g., "06", "01", "03", "92" |
serviceName | serviceName | e.g., "FedEx International First" |
speed | Derived from serviceType | See speed mapping below |
features | Derived from response | See features extraction below |
baseRate | ratedShipmentDetails[0].totalBaseCharge | Use ACCOUNT rate type |
additionalFees | ratedShipmentDetails[0].shipmentRateDetail.surCharges[] | Mapped to Fee[] |
totalCost | ratedShipmentDetails[0].totalNetCharge | Use ACCOUNT rate type |
estimatedDeliveryDate | commit.dateDetail.dayCxsFormat | Parse to Date object |
guaranteedDelivery | !operationalDetail.ineligibleForMoneyBackGuarantee | Inverted boolean |
Speed Mapping
Map serviceType to internal ServiceSpeed:
typescript1const speedMap: Record<string, ServiceSpeed> = {2 'INTERNATIONAL_FIRST': 'overnight',3 'PRIORITY_OVERNIGHT': 'overnight',4 'FIRST_OVERNIGHT': 'overnight',5 'INTERNATIONAL_PRIORITY': 'two-day',6 'FEDEX_2_DAY': 'two-day',7 'INTERNATIONAL_ECONOMY': 'standard',8 'FEDEX_EXPRESS_SAVER': 'standard',9 'FEDEX_GROUND': 'economy',10 'GROUND_HOME_DELIVERY': 'economy',11};
Features Extraction
Extract features from multiple response fields:
typescript1function extractFeatures(detail: RateReplyDetail): string[] {2 const features: string[] = [];34 // Signature option5 if (detail.signatureOptionType !== 'SERVICE_DEFAULT') {6 features.push('Signature Required');7 }89 // Delivery day10 if (detail.operationalDetail?.deliveryDay) {11 features.push(`Delivers ${detail.operationalDetail.deliveryDay}`);12 }1314 // Transit time15 if (detail.operationalDetail?.transitTime) {16 features.push(formatTransitTime(detail.operationalDetail.transitTime));17 }1819 // Money-back guarantee20 if (!detail.operationalDetail?.ineligibleForMoneyBackGuarantee) {21 features.push('Money-Back Guarantee');22 }2324 return features;25}
Surcharges to Fee Mapping
Map surCharges[] to internal Fee[]:
typescript1function mapSurchargeToFee(surcharge: FedExSurcharge): Fee {2 return {3 type: mapSurchargeType(surcharge.type),4 amount: surcharge.amount,5 description: surcharge.description,6 };7}89// FedEx surcharge types we handle:10// - FUEL -> included in base rate calculation11// - RESIDENTIAL_DELIVERY -> additional fee12// - SIGNATURE_OPTION -> 'signature' fee13// - DECLARED_VALUE -> 'insurance' fee14// - SATURDAY_DELIVERY -> 'saturdayDelivery' fee
Rate Type Selection
FedEx returns multiple ratedShipmentDetails entries with different rateType values:
| rateType | Description | Use Case |
|---|---|---|
ACCOUNT | Negotiated account rates | Use for authenticated users |
LIST | Published list rates | Fallback if no account |
PREFERRED_INCENTIVE | Promotional rates | Display as savings |
PREFERRED_CURRENCY | Rates in preferred currency | Multi-currency support |
Selection logic:
typescript1function selectRate(details: RatedShipmentDetail[]): RatedShipmentDetail {2 return details.find(d => d.rateType === 'ACCOUNT')3 ?? details.find(d => d.rateType === 'LIST')4 ?? details[0];5}
Complete Adapter Implementation
typescript1function adaptFedExRate(detail: RateReplyDetail): ShippingRate {2 const rateDetail = selectRate(detail.ratedShipmentDetails);3 const shipmentDetail = rateDetail.shipmentRateDetail;45 return {6 id: `fedex-${detail.serviceType}-${Date.now()}`,7 carrier: 'FedEx',8 serviceCode: detail.serviceDescription.code,9 serviceName: detail.serviceName,10 speed: speedMap[detail.serviceType] ?? 'standard',11 features: extractFeatures(detail),12 baseRate: rateDetail.totalBaseCharge,13 additionalFees: shipmentDetail.surCharges?.map(mapSurchargeToFee) ?? [],14 totalCost: rateDetail.totalNetCharge,15 estimatedDeliveryDate: parseDeliveryDate(detail),16 guaranteedDelivery: !detail.operationalDetail?.ineligibleForMoneyBackGuarantee,17 };18}1920function adaptFedExResponse(response: FedExRateResponse): ShippingRate[] {21 return response.output.rateReplyDetails.map(adaptFedExRate);22}
Delivery Date Parsing
Extract delivery date from multiple possible locations:
typescript1function parseDeliveryDate(detail: RateReplyDetail): Date {2 // Primary: commit date detail3 if (detail.commit?.dateDetail?.dayCxsFormat) {4 return new Date(detail.commit.dateDetail.dayCxsFormat);5 }67 // Fallback: operational detail commit date8 if (detail.operationalDetail?.commitDate) {9 return new Date(detail.operationalDetail.commitDate);10 }1112 // Last resort: calculate from transit time13 return calculateFromTransitTime(detail.operationalDetail?.transitTime);14}
Error Handling
The response may include alerts in output.alerts[]. Handle these appropriately:
typescript1interface FedExAlert {2 code: string;3 message: string;4 alertType: 'NOTE' | 'WARNING' | 'ERROR';5}67function handleAlerts(alerts: FedExAlert[]): void {8 const errors = alerts.filter(a => a.alertType === 'ERROR');9 if (errors.length > 0) {10 throw new CarrierError('FedEx', errors[0].message, false);11 }1213 // Log warnings for monitoring14 alerts.filter(a => a.alertType === 'WARNING')15 .forEach(a => console.warn(`FedEx: ${a.message}`));16}
Example Transformation
Input (one service from FedEx response):
json1{2 "serviceType": "INTERNATIONAL_PRIORITY",3 "serviceName": "FedEx International Priority",4 "ratedShipmentDetails": [{5 "rateType": "ACCOUNT",6 "totalBaseCharge": 312.35,7 "totalNetCharge": 345.15,8 "shipmentRateDetail": {9 "surCharges": [{10 "type": "FUEL",11 "description": "Fuel Surcharge",12 "amount": 32.813 }]14 }15 }],16 "operationalDetail": {17 "transitTime": "THREE_DAYS",18 "ineligibleForMoneyBackGuarantee": false19 },20 "serviceDescription": { "code": "01" },21 "commit": {22 "dateDetail": { "dayCxsFormat": "2020-07-16T10:30:00" }23 }24}
Output (ShippingRate):
typescript1{2 id: 'fedex-INTERNATIONAL_PRIORITY-1697654321000',3 carrier: 'FedEx',4 serviceCode: '01',5 serviceName: 'FedEx International Priority',6 speed: 'two-day',7 features: ['Delivers TUE', '3 Days', 'Money-Back Guarantee'],8 baseRate: 312.35,9 additionalFees: [{10 type: 'fuel',11 amount: 32.8,12 description: 'Fuel Surcharge'13 }],14 totalCost: 345.15,15 estimatedDeliveryDate: new Date('2020-07-16T10:30:00'),16 guaranteedDelivery: true17}