30 minlesson

FedEx Rate API Response Mapping

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


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 FieldFedEx Response PathNotes
idGeneratedfedex-${serviceType}-${timestamp}
carrierConstant'FedEx'
serviceCodeserviceDescription.codee.g., "06", "01", "03", "92"
serviceNameserviceNamee.g., "FedEx International First"
speedDerived from serviceTypeSee speed mapping below
featuresDerived from responseSee features extraction below
baseRateratedShipmentDetails[0].totalBaseChargeUse ACCOUNT rate type
additionalFeesratedShipmentDetails[0].shipmentRateDetail.surCharges[]Mapped to Fee[]
totalCostratedShipmentDetails[0].totalNetChargeUse ACCOUNT rate type
estimatedDeliveryDatecommit.dateDetail.dayCxsFormatParse to Date object
guaranteedDelivery!operationalDetail.ineligibleForMoneyBackGuaranteeInverted boolean

Speed Mapping

Map serviceType to internal ServiceSpeed:

typescript
1const 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:

typescript
1function extractFeatures(detail: RateReplyDetail): string[] {
2 const features: string[] = [];
3
4 // Signature option
5 if (detail.signatureOptionType !== 'SERVICE_DEFAULT') {
6 features.push('Signature Required');
7 }
8
9 // Delivery day
10 if (detail.operationalDetail?.deliveryDay) {
11 features.push(`Delivers ${detail.operationalDetail.deliveryDay}`);
12 }
13
14 // Transit time
15 if (detail.operationalDetail?.transitTime) {
16 features.push(formatTransitTime(detail.operationalDetail.transitTime));
17 }
18
19 // Money-back guarantee
20 if (!detail.operationalDetail?.ineligibleForMoneyBackGuarantee) {
21 features.push('Money-Back Guarantee');
22 }
23
24 return features;
25}

Surcharges to Fee Mapping

Map surCharges[] to internal Fee[]:

typescript
1function mapSurchargeToFee(surcharge: FedExSurcharge): Fee {
2 return {
3 type: mapSurchargeType(surcharge.type),
4 amount: surcharge.amount,
5 description: surcharge.description,
6 };
7}
8
9// FedEx surcharge types we handle:
10// - FUEL -> included in base rate calculation
11// - RESIDENTIAL_DELIVERY -> additional fee
12// - SIGNATURE_OPTION -> 'signature' fee
13// - DECLARED_VALUE -> 'insurance' fee
14// - SATURDAY_DELIVERY -> 'saturdayDelivery' fee

Rate Type Selection

FedEx returns multiple ratedShipmentDetails entries with different rateType values:

rateTypeDescriptionUse Case
ACCOUNTNegotiated account ratesUse for authenticated users
LISTPublished list ratesFallback if no account
PREFERRED_INCENTIVEPromotional ratesDisplay as savings
PREFERRED_CURRENCYRates in preferred currencyMulti-currency support

Selection logic:

typescript
1function 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

typescript
1function adaptFedExRate(detail: RateReplyDetail): ShippingRate {
2 const rateDetail = selectRate(detail.ratedShipmentDetails);
3 const shipmentDetail = rateDetail.shipmentRateDetail;
4
5 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}
19
20function adaptFedExResponse(response: FedExRateResponse): ShippingRate[] {
21 return response.output.rateReplyDetails.map(adaptFedExRate);
22}

Delivery Date Parsing

Extract delivery date from multiple possible locations:

typescript
1function parseDeliveryDate(detail: RateReplyDetail): Date {
2 // Primary: commit date detail
3 if (detail.commit?.dateDetail?.dayCxsFormat) {
4 return new Date(detail.commit.dateDetail.dayCxsFormat);
5 }
6
7 // Fallback: operational detail commit date
8 if (detail.operationalDetail?.commitDate) {
9 return new Date(detail.operationalDetail.commitDate);
10 }
11
12 // Last resort: calculate from transit time
13 return calculateFromTransitTime(detail.operationalDetail?.transitTime);
14}

Error Handling

The response may include alerts in output.alerts[]. Handle these appropriately:

typescript
1interface FedExAlert {
2 code: string;
3 message: string;
4 alertType: 'NOTE' | 'WARNING' | 'ERROR';
5}
6
7function 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 }
12
13 // Log warnings for monitoring
14 alerts.filter(a => a.alertType === 'WARNING')
15 .forEach(a => console.warn(`FedEx: ${a.message}`));
16}

Example Transformation

Input (one service from FedEx response):

json
1{
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.8
13 }]
14 }
15 }],
16 "operationalDetail": {
17 "transitTime": "THREE_DAYS",
18 "ineligibleForMoneyBackGuarantee": false
19 },
20 "serviceDescription": { "code": "01" },
21 "commit": {
22 "dateDetail": { "dayCxsFormat": "2020-07-16T10:30:00" }
23 }
24}

Output (ShippingRate):

typescript
1{
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: true
17}