# How to Integrate Lovable with FedEx API

- Tool: Lovable
- Difficulty: Intermediate
- Time required: 45 minutes
- Last updated: March 2026

## TL;DR

To integrate FedEx with Lovable, create a Supabase Edge Function that authenticates with FedEx's OAuth2 API using your Client ID and Secret stored in Cloud Secrets. The Edge Function proxies rate calculations, shipment creation, and tracking requests to FedEx's new REST API — replacing the deprecated SOAP/XML API — keeping credentials server-side and never visible to the browser. Setup takes about 45 minutes.

## Add FedEx Shipping Rates, Labels, and Tracking to Your Lovable App

FedEx dominates overnight and express shipping in the US — FedEx Priority Overnight, FedEx 2Day, and FedEx Express Saver are the services customers reach for when they need fast, reliable domestic delivery. The FedEx API lets you embed FedEx rate calculations directly into your checkout flow, generate FedEx labels from within your app, and power real-time tracking pages with FedEx shipment event data. If your customers expect FedEx shipping options, this integration brings them into your Lovable app.

FedEx migrated from its legacy SOAP/XML web services to a modern REST API in 2022-2023. This guide covers the new REST API exclusively — if you've seen older FedEx integration guides using WSDL files and SOAP envelopes, those approaches are deprecated. The new REST API uses OAuth2 client credentials flow for authentication, standard JSON request/response bodies, and a straightforward endpoint structure at apis.fedex.com. The auth model means your Edge Function first obtains a short-lived bearer token, then uses that token for rate, shipment, and tracking calls.

FedEx differs from UPS in service emphasis: FedEx is generally stronger for overnight and time-definite express delivery, particularly within the continental US. FedEx Ground is competitive for domestic ground shipping, and FedEx International Priority leads for fast international delivery. For apps serving customers who prioritize speed over price — electronics, perishables, medical supplies, urgent documents — FedEx is typically the carrier of choice.

## Before you start

- A FedEx Developer Portal account at developer.fedex.com — create a free developer account and create a FedEx app to get your Client ID and Client Secret
- A FedEx business account number — required for rate calculations and label generation (FedEx provides a test account number for sandbox testing)
- A Lovable project with Lovable Cloud enabled (the default for all new projects)
- Your origin address (warehouse or shipping location) with postal code and country — used in all rate calculation requests
- Understanding that the new FedEx REST API is completely different from legacy FedEx SOAP web services — do not use SOAP-based examples from older guides

## Step-by-step guide

### 1. Create a FedEx developer app and get credentials

Navigate to developer.fedex.com and sign in or create a free developer account. Once logged in, go to My Projects → Create Project. Give the project a name (e.g., 'Lovable App') and select the APIs you need access to — at minimum, select Rate Quotes, Ship, and Track. After creating the project, FedEx generates a Client ID and Client Secret visible on the project detail page.

For sandbox testing, FedEx provides a test environment at apis-sandbox.fedex.com. The sandbox uses the same OAuth2 flow as production but with test credentials that don't generate real shipments or charges. Your developer portal project gives you both sandbox and production credential sets — start with sandbox credentials during development. The test account number for sandbox use is shown in the FedEx developer documentation; use this as the shipper account number in rate and shipment requests during testing.

Note that FedEx's new REST API is versioned — the current base paths are /rate/v1/rates/quotes for rates, /ship/v1/shipments for shipment creation, and /track/v1/trackingnumbers for tracking. The authentication endpoint is /oauth/token. Copy your Client ID and Client Secret from the project page before moving to the next step.

**Expected result:** You have a FedEx Client ID and Client Secret from your developer portal project page, and know whether you're using sandbox (apis-sandbox.fedex.com) or production (apis.fedex.com) credentials.

### 2. Store FedEx credentials in Cloud Secrets

In your Lovable project, click the '+' icon next to the Preview panel to open the Cloud tab. Click Secrets in the left sidebar. Click Add Secret and create the following secrets:

Add FEDEX_CLIENT_ID with your FedEx Client ID as the value. Add FEDEX_CLIENT_SECRET with your Client Secret. Add FEDEX_ACCOUNT_NUMBER with your FedEx account number (or the sandbox test account number). Add FEDEX_ENV with value 'sandbox' for development (change to 'production' when going live).

FedEx's OAuth2 client credentials flow generates short-lived access tokens (typically valid for 60 minutes). Your Edge Function will exchange the Client ID and Secret for a bearer token each time it's called, or cache the token with its TTL to avoid unnecessary token requests. The client secret in particular must never appear in frontend code — it grants the ability to authenticate as your FedEx account and generate real shipping labels. Lovable's Cloud Secrets panel stores all values encrypted and immutable from the browser — only Edge Functions via Deno.env.get() can read them. Lovable's security system actively prevents approximately 1,200 hardcoded API keys daily from reaching production code.

**Expected result:** Cloud → Secrets shows FEDEX_CLIENT_ID, FEDEX_CLIENT_SECRET, FEDEX_ACCOUNT_NUMBER, and FEDEX_ENV as encrypted entries.

### 3. Create the FedEx Edge Function proxy

Create the Edge Function that handles FedEx OAuth2 authentication and proxies API calls. Type the following prompt into Lovable's chat. Lovable will generate the TypeScript at supabase/functions/fedex-proxy/index.ts and deploy it to Cloud.

The Edge Function first calls the FedEx OAuth2 token endpoint with the Client ID and Secret to obtain a bearer token, then uses that token to call the Rate, Ship, or Track APIs based on the 'action' query parameter. The token exchange uses the 'client_credentials' grant type and a 'client_id:client_secret' Basic Auth header as required by FedEx's auth spec.

For rate requests, the FedEx Rate API expects a JSON body with requestedShipment containing shipper and recipient addresses, rateRequestType ('LIST' for published rates, 'ACCOUNT' for account rates), and requested package details. The Edge Function maps simpler frontend-friendly parameters to this structure. CORS headers are included on all responses.

```
import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
}

async function getFedExToken(clientId: string, clientSecret: string, baseUrl: string): Promise<string> {
  const response = await fetch(`${baseUrl}/oauth/token`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'client_credentials',
      client_id: clientId,
      client_secret: clientSecret,
    }),
  })
  const data = await response.json()
  if (!response.ok) throw new Error(`FedEx auth error: ${JSON.stringify(data)}`)
  return data.access_token
}

serve(async (req) => {
  if (req.method === 'OPTIONS') {
    return new Response('ok', { headers: corsHeaders })
  }

  try {
    const clientId = Deno.env.get('FEDEX_CLIENT_ID')
    const clientSecret = Deno.env.get('FEDEX_CLIENT_SECRET')
    const accountNumber = Deno.env.get('FEDEX_ACCOUNT_NUMBER')
    const env = Deno.env.get('FEDEX_ENV') || 'sandbox'
    const baseUrl = env === 'production'
      ? 'https://apis.fedex.com'
      : 'https://apis-sandbox.fedex.com'

    if (!clientId || !clientSecret || !accountNumber) {
      return new Response(
        JSON.stringify({ error: 'FedEx credentials not configured in Cloud Secrets' }),
        { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    const accessToken = await getFedExToken(clientId, clientSecret, baseUrl)
    const url = new URL(req.url)
    const action = url.searchParams.get('action')

    const fedexHeaders = {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
      'X-locale': 'en_US',
    }

    let endpoint: string
    const bodyText = await req.text()
    const bodyJson = bodyText ? JSON.parse(bodyText) : {}

    if (action === 'rates') {
      // Inject account number into the rate request
      if (bodyJson.accountNumber) bodyJson.accountNumber = { value: accountNumber }
      endpoint = `${baseUrl}/rate/v1/rates/quotes`
    } else if (action === 'ship') {
      endpoint = `${baseUrl}/ship/v1/shipments`
    } else if (action === 'track') {
      endpoint = `${baseUrl}/track/v1/trackingnumbers`
    } else {
      return new Response(
        JSON.stringify({ error: 'Invalid action. Use: rates, ship, or track' }),
        { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
      )
    }

    const fedexRes = await fetch(endpoint, {
      method: 'POST',
      headers: fedexHeaders,
      body: JSON.stringify(bodyJson),
    })

    const data = await fedexRes.json()
    return new Response(JSON.stringify(data), {
      status: fedexRes.status,
      headers: { ...corsHeaders, 'Content-Type': 'application/json' },
    })
  } catch (error) {
    return new Response(
      JSON.stringify({ error: error.message }),
      { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
    )
  }
})
```

**Expected result:** Lovable deploys the fedex-proxy Edge Function to Cloud. The function handles OAuth2 token acquisition and proxies Rate, Ship, and Track API calls.

### 4. Build the FedEx rate calculator and test end-to-end

With the Edge Function deployed, ask Lovable to build the rate calculator UI. The FedEx Rate API request body requires a specific JSON structure: a requestedShipment object containing shipper and recipient addresses (with postalCode, countryCode, stateOrProvinceCode, city), pickupType ('DROPOFF_AT_FEDEX_LOCATION' or 'USE_SCHEDULED_PICKUP'), serviceType (leave empty to get all available services), rateRequestType array (['ACCOUNT', 'LIST']), and requestedPackageLineItems array with weight and dimensions.

The Rate API response includes an output.rateReplyDetails array where each item represents an available FedEx service (Priority Overnight, 2Day, Express Saver, Ground, etc.) with ratedShipmentDetails containing the totalNetCharge and currency, plus commit.dateDetail.dayFormat for the delivery date.

Test the integration in sandbox mode using FedEx's published test addresses and tracking numbers from the developer documentation. Once sandbox testing confirms rates and tracking work correctly, update Cloud Secrets with production credentials by changing FEDEX_ENV to 'production' and updating FEDEX_CLIENT_ID and FEDEX_CLIENT_SECRET to your production values. For complex shipping scenarios like hazardous materials, alcohol, or medical devices — which require special FedEx approvals and additional API fields — RapidDev's team can help configure the correct commodity and special handling codes.

**Expected result:** The FedEx rate calculator renders in Lovable preview. Entering test addresses and package dimensions returns FedEx service options with prices and delivery dates from the sandbox API.

## Best practices

- Always start with FedEx sandbox credentials (apis-sandbox.fedex.com) during development and switch to production only when your integration is fully tested — sandbox mistakes don't create real shipments or charges.
- Cache FedEx OAuth2 tokens with their TTL rather than requesting a new token on every API call — tokens are valid for 60 minutes and unnecessary token requests add latency and may trigger FedEx rate limits.
- Include both 'LIST' and 'ACCOUNT' in the rateRequestType array to get both published retail rates and your FedEx account rates in a single request — account rates are often lower and show the actual cost.
- Store FedEx tracking numbers in Supabase immediately after shipment creation — if the label generation succeeds but your frontend crashes before displaying the tracking number, you need the database record to recover it.
- Implement a fallback to show 'Rates temporarily unavailable' if the FedEx API returns an error at checkout, rather than blocking the customer from completing their purchase with an unknown shipping cost.
- Use FedEx Address Validation API (/address/v1/addresses/resolve) to validate customer addresses before requesting rates — invalid addresses that pass client-side validation still cause rate request failures.
- Test your integration with a variety of package weights, dimensions, and destinations before launch — some FedEx services have dimensional weight pricing rules that can produce unexpected pricing for large, light packages.

## Use cases

### FedEx rate calculator at checkout

Display available FedEx service options to customers at checkout with live rate quotes, estimated delivery dates, and delivery time guarantees. Customers can compare FedEx Priority Overnight, 2Day, Express Saver, and Ground options before choosing.

Prompt example:

```
Create a FedEx shipping rate calculator component that calls a fedex-proxy Edge Function. The form takes recipient address (street, city, state, zip, country), package weight in pounds, and dimensions in inches. Call the FedEx Rate API via the Edge Function and display each returned service (name, price, delivery date, time-in-transit) as a selectable option card. Sort by delivery speed with overnight options first. Store my FedEx Client ID and Secret in Cloud Secrets.
```

### FedEx label generation for order fulfillment

Generate FedEx shipping labels for fulfilled orders directly from your order management page in Lovable. The Edge Function calls FedEx's Ship API with the order's destination address and package details, returning a base64-encoded label for printing.

Prompt example:

```
Add a Ship with FedEx button to my order management page. When clicked, open a modal showing FedEx rate options for the order. When the admin selects a service and confirms, call the fedex-proxy Edge Function to create a FedEx shipment and generate a label. Display the tracking number and a Download PDF Label button. Save the FedEx tracking number and selected service to the order record in Supabase.
```

### Real-time FedEx package tracking

Build a package tracking page that customers can use to look up their FedEx shipment by tracking number. The Edge Function calls FedEx's Track API and returns a detailed timeline of shipment events with locations and timestamps.

Prompt example:

```
Create a package tracking page where customers enter their FedEx tracking number. Call the fedex-proxy Edge Function with the tracking number using the FedEx Track API. Display a timeline of tracking events: each showing the date, time, location city/state, and event description (e.g., 'Picked up', 'Arrived at facility', 'On FedEx vehicle for delivery'). Show the estimated delivery date prominently at the top. Handle the case where tracking is not yet available for new shipments.
```

## Troubleshooting

### OAuth2 token request returns 'invalid.client.credentials' error

Cause: The Client ID or Client Secret in Cloud Secrets is incorrect, the credentials belong to a different environment (sandbox vs production), or the FedEx developer account hasn't been fully provisioned.

Solution: Log in to developer.fedex.com and verify the Client ID and Secret on your project's API credentials page. Confirm whether your project is configured for sandbox or production, and ensure FEDEX_ENV in Cloud Secrets matches. New FedEx developer accounts may take 24-48 hours to activate — if you just registered, wait and retry.

### Rate API returns 'DESTINATION.COUNTRYCODE.INVALID' or similar validation errors

Cause: The address fields in the rate request use incorrect field names or formats. FedEx REST API address fields differ from the legacy SOAP API and from other carriers' formats.

Solution: Verify your address structure uses the exact field names expected by the FedEx REST API: 'postalCode' (not 'zip'), 'countryCode' (ISO 2-letter), 'stateOrProvinceCode' (2-letter for US states), and 'city'. Log the full request body being sent to the Edge Function to confirm the structure before the API call.

```
// Correct FedEx address structure
const fedexAddress = {
  streetLines: ['123 Main St'],
  city: 'Memphis',
  stateOrProvinceCode: 'TN',
  postalCode: '38103',
  countryCode: 'US'
}
```

### Track API returns no tracking results for a known tracking number

Cause: The FedEx REST Track API requires the tracking number wrapped in a specific JSON structure, not passed as a URL parameter like older SOAP-based tracking.

Solution: The FedEx Track API (POST /track/v1/trackingnumbers) expects a JSON body with a trackingInfo array, where each item has a trackingNumberInfo object containing the trackingNumber string. Ensure the request body from the Edge Function matches this structure exactly.

```
// Correct FedEx Track API request body
const trackBody = {
  includeDetailedScans: true,
  trackingInfo: [
    {
      trackingNumberInfo: {
        trackingNumber: '123456789012'
      }
    }
  ]
}
```

### Edge Function returns credentials-not-found error (P0001) in Cloud Logs

Cause: The secret names in Deno.env.get() calls don't match the names stored in Cloud → Secrets exactly, including case sensitivity.

Solution: Open Cloud → Secrets and verify the exact names of your FedEx secrets match what the Edge Function code uses. FedEx secret names are case-sensitive. 'FEDEX_CLIENT_ID' and 'fedex_client_id' are different secrets. Update the secret names in Cloud → Secrets or the Edge Function code to match exactly, then redeploy via Lovable chat.

## Frequently asked questions

### What happened to the FedEx SOAP/XML web services?

FedEx deprecated its legacy SOAP-based web services in favor of the new REST API. The legacy Web Services API was officially retired in 2024. All new integrations must use the REST API documented at developer.fedex.com. If you have an existing integration using SOAP/WSDL, you'll need to migrate to the REST API — the authentication model, endpoint structure, and request/response formats are completely different.

### Do I need a FedEx business account to use the API?

For sandbox testing, FedEx provides a test account number — no business account needed. For production use (generating real labels and processing real shipments), you need a FedEx business account. Create one at fedex.com/signup. Business accounts give you account-specific rates that are typically lower than published retail rates, which appear in your app's shipping calculator when you include 'ACCOUNT' in the rateRequestType parameter.

### Why is FedEx better than UPS for overnight shipping?

FedEx generally has stronger overnight and express service networks within the continental US, particularly for business-to-business shipments. FedEx Priority Overnight is widely recognized for reliability and time-definite delivery guarantees. That said, actual service quality and pricing varies by origin-destination pair — it's worth comparing both UPS Next Day Air and FedEx Priority Overnight rates for your specific shipping lanes using real API calls to determine which carrier is better for your use case.

### How do I switch from FedEx sandbox to production?

Update three Cloud Secrets: change FEDEX_ENV from 'sandbox' to 'production', update FEDEX_CLIENT_ID to your production Client ID, and update FEDEX_CLIENT_SECRET to your production Client Secret. The Edge Function code requires no changes — it reads the environment from FEDEX_ENV to switch between apis-sandbox.fedex.com and apis.fedex.com. Run a test rate request after updating secrets to confirm production credentials work before routing live customer traffic.

### Can I offer FedEx rates alongside other carriers in the same checkout?

Yes — this is a common pattern using Shippo as a multi-carrier aggregator. Shippo's API returns FedEx rates alongside USPS, UPS, and other carriers in a single call, using Shippo's negotiated FedEx rates. Alternatively, you can call multiple carrier-specific Edge Functions in parallel from your React checkout component. Using Shippo is simpler if you want multi-carrier comparison; direct FedEx API integration gives you access to your specific FedEx account rates and the full FedEx service catalog.

---

Source: https://www.rapidevelopers.com/lovable-integration/fedex-api
© RapidDev — https://www.rapidevelopers.com/lovable-integration/fedex-api
