To integrate Freightos WebCargo with Lovable, create a Supabase Edge Function that proxies freight quote, booking, and tracking requests using your Freightos API credentials stored in Cloud Secrets. This lets you build freight rate comparison tools, container and air freight calculators, and shipment tracking dashboards in Lovable without exposing credentials in frontend code. Setup takes about 50 minutes.
Build a Freight Rate Comparison Tool in Lovable with Freightos WebCargo
Moving bulk cargo — pallets, containers, air freight consignments — involves comparing dozens of freight forwarders and carriers across wildly different price points and transit times. Freightos WebCargo is the API that powers this comparison in real time: connect once to Freightos and get instant rate quotes from 50+ freight carriers across ocean LCL (less than container load), FCL (full container), air freight, and express freight. Integrating Freightos into Lovable lets you build freight rate calculators, logistics portals, and supply chain dashboards for your users without building direct relationships with each carrier.
The Freightos WebCargo API differs from single-carrier APIs like DHL or UPS in that it's a marketplace: a single rate request goes out to multiple freight forwarders simultaneously, and their quotes come back asynchronously. This means the integration pattern involves polling for results rather than waiting for a single synchronous response — some carriers respond in seconds, others in minutes. Your Edge Function handles this polling loop server-side, collecting available quotes and returning them to the React frontend as they arrive.
This type of integration is particularly valuable for e-commerce apps serving wholesale buyers, B2B platforms where customers purchase in bulk and need freight cost visibility, and logistics SaaS tools that help importers and exporters compare shipping options. Freightos covers the major global trade lanes — Asia to North America, Europe to Asia, transatlantic — with the carrier network depth that makes real rate comparison practical rather than theoretical.
Integration method
Freightos WebCargo API integration in Lovable works by routing all requests through Supabase Edge Functions running on Deno. Your Freightos API credentials are stored encrypted in Cloud → Secrets and accessed via Deno.env.get() — never exposed to the browser. The React frontend calls the Edge Function, which authenticates with the Freightos WebCargo API and returns freight rate quotes, booking confirmations, and tracking updates.
Prerequisites
- A Freightos WebCargo API account — apply at freightos.com/freight-tools/freightos-api/ (API access requires business approval, not instant signup)
- Your Freightos API Client ID and Client Secret from your WebCargo API dashboard after approval
- Understanding of freight shipping terminology: LCL (less than container load), FCL (full container load), CBM (cubic meters), Incoterms
- A Lovable project with Lovable Cloud enabled (the default for all new projects)
- An app use case involving bulk cargo shipping — Freightos is designed for freight (pallets, containers), not parcel shipping; use DHL, UPS, or Shippo for parcel rates
Step-by-step guide
Obtain Freightos WebCargo API access and credentials
Obtain Freightos WebCargo API access and credentials
Freightos WebCargo API access is not self-service — it requires a business application and approval process. Navigate to freightos.com/freight-tools/freightos-api/ and click Request API Access. Fill in your company details, intended use case (e.g., 'Building a freight rate calculator for B2B e-commerce buyers'), and expected monthly quote volume. Freightos reviews applications to ensure the integration makes business sense and that the applicant has a legitimate freight use case. Once approved (typically 3-7 business days), you'll receive access to the Freightos WebCargo API portal where you can generate your Client ID and Client Secret. These are OAuth2 credentials used to obtain bearer tokens for API authentication. The WebCargo API documentation, available at developer.freightos.com, covers the full rate request and booking flow including the asynchronous quote collection pattern. Freightos provides a sandbox environment for development. The sandbox simulates carrier responses with mock data so you can build and test your integration without requesting real freight quotes or making actual bookings. Note your Client ID and Client Secret from the API portal — you'll need both for the Cloud Secrets step. Also note whether your access is for the production API or sandbox, as the base URLs differ.
Pro tip: When filling out the Freightos API access form, mention specific trade lanes and cargo types you'll be rating (e.g., 'Ocean LCL from Shanghai to Los Angeles for e-commerce pallets') — this specificity helps approval and ensures your account is configured for the right carrier network segments.
Expected result: You have a Freightos WebCargo API Client ID and Client Secret, and understand whether you're starting with the sandbox or production environment.
Store Freightos credentials in Cloud Secrets
Store Freightos credentials in Cloud Secrets
With your Freightos credentials in hand, store them securely in Lovable's Cloud Secrets panel. In your Lovable project, click the '+' icon next to the Preview panel at the top to open the Cloud tab. Inside the Cloud tab, click Secrets in the left sidebar. Click Add Secret for each credential. Add FREIGHTOS_CLIENT_ID with your Client ID value and click Save. Add FREIGHTOS_CLIENT_SECRET with your Client Secret value and click Save. If you're using the Freightos sandbox, also add FREIGHTOS_ENV with value 'sandbox' so your Edge Function knows which base URL to use. For production, set it to 'production'. Never paste Freightos credentials into Lovable's chat prompt — the Freightos Client Secret in particular is a sensitive OAuth2 credential that grants access to quote real freight rates on your account. Lovable's Cloud Secrets panel encrypts values at rest with the same security posture as Supabase's encrypted secrets (SOC 2 Type II certified). Once stored, the values are only accessible from your Edge Functions via Deno.env.get(), never from the React frontend or browser.
Pro tip: Freightos uses OAuth2 client credentials flow — your Edge Function exchanges the Client ID and Secret for a bearer token, then uses that token for subsequent API calls. The token has a TTL; cache it in the Edge Function memory between requests rather than fetching a new token on every API call.
Expected result: Cloud → Secrets shows FREIGHTOS_CLIENT_ID, FREIGHTOS_CLIENT_SECRET, and FREIGHTOS_ENV as encrypted entries.
Create the Freightos Edge Function proxy
Create the Freightos Edge Function proxy
Create the Edge Function that handles Freightos API authentication and proxies rate, booking, and tracking requests. Type the following prompt into Lovable's chat. Lovable will generate the TypeScript code at supabase/functions/freightos-proxy/index.ts and deploy it to Cloud. The Edge Function handles two key concerns: OAuth2 token management and request routing. The function first calls Freightos's token endpoint with the Client ID and Secret to get a bearer token, then uses that token to call the actual API endpoints. The Freightos WebCargo API uses an asynchronous rate request pattern: you submit a rate request and receive a request ID, then poll a status endpoint until all carrier quotes have been collected. The Edge Function implements this polling loop — waiting for quotes to accumulate and returning results when complete or when a timeout is reached. Three actions are supported: 'quote' (submit a freight rate request and poll for results), 'book' (confirm a booking from a quote), and 'track' (get tracking milestones for a booking reference). CORS headers are included on all responses for browser compatibility.
Create a Supabase Edge Function at supabase/functions/freightos-proxy/index.ts for the Freightos WebCargo API. Use Deno.env.get('FREIGHTOS_CLIENT_ID') and Deno.env.get('FREIGHTOS_CLIENT_SECRET') to get an OAuth2 bearer token from https://api.webcargo.co/oauth/token (use https://api-sandbox.webcargo.co for sandbox). Support three actions via query parameter: 'quote' (POST to /rates with cargo details in the request body, poll for results up to 30 seconds), 'book' (POST to /bookings with quote ID and shipper details), and 'track' (GET /shipments/{bookingRef}/milestones). Include CORS headers. Use FREIGHTOS_ENV to switch between sandbox and production base URLs.
Paste this in Lovable chat
1import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'23const corsHeaders = {4 'Access-Control-Allow-Origin': '*',5 'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',6}78async function getAccessToken(clientId: string, clientSecret: string, isSandbox: boolean): Promise<string> {9 const tokenUrl = isSandbox10 ? 'https://api-sandbox.webcargo.co/oauth/token'11 : 'https://api.webcargo.co/oauth/token'1213 const response = await fetch(tokenUrl, {14 method: 'POST',15 headers: { 'Content-Type': 'application/x-www-form-urlencoded' },16 body: new URLSearchParams({17 grant_type: 'client_credentials',18 client_id: clientId,19 client_secret: clientSecret,20 }),21 })2223 const data = await response.json()24 if (!response.ok) throw new Error(`Token error: ${data.error_description || data.error}`)25 return data.access_token26}2728serve(async (req) => {29 if (req.method === 'OPTIONS') {30 return new Response('ok', { headers: corsHeaders })31 }3233 try {34 const clientId = Deno.env.get('FREIGHTOS_CLIENT_ID')35 const clientSecret = Deno.env.get('FREIGHTOS_CLIENT_SECRET')36 const env = Deno.env.get('FREIGHTOS_ENV') || 'sandbox'37 const isSandbox = env === 'sandbox'3839 if (!clientId || !clientSecret) {40 return new Response(41 JSON.stringify({ error: 'Freightos credentials not configured in Cloud Secrets' }),42 { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }43 )44 }4546 const accessToken = await getAccessToken(clientId, clientSecret, isSandbox)47 const baseUrl = isSandbox ? 'https://api-sandbox.webcargo.co/v2' : 'https://api.webcargo.co/v2'4849 const url = new URL(req.url)50 const action = url.searchParams.get('action')5152 const authHeaders = {53 'Authorization': `Bearer ${accessToken}`,54 'Content-Type': 'application/json',55 'Accept': 'application/json',56 }5758 if (action === 'quote') {59 const body = await req.text()60 // Submit rate request61 const quoteRes = await fetch(`${baseUrl}/rates`, {62 method: 'POST',63 headers: authHeaders,64 body,65 })66 const quoteData = await quoteRes.json()6768 if (!quoteRes.ok) {69 return new Response(JSON.stringify(quoteData), {70 status: quoteRes.status,71 headers: { ...corsHeaders, 'Content-Type': 'application/json' },72 })73 }7475 const requestId = quoteData.id76 // Poll for results up to 30 seconds77 let results = quoteData78 for (let i = 0; i < 15; i++) {79 await new Promise(resolve => setTimeout(resolve, 2000))80 const pollRes = await fetch(`${baseUrl}/rates/${requestId}`, { headers: authHeaders })81 results = await pollRes.json()82 if (results.status === 'COMPLETED' || (results.quotes && results.quotes.length > 0)) break83 }8485 return new Response(JSON.stringify(results), {86 headers: { ...corsHeaders, 'Content-Type': 'application/json' },87 })88 } else if (action === 'book') {89 const body = await req.text()90 const bookRes = await fetch(`${baseUrl}/bookings`, {91 method: 'POST',92 headers: authHeaders,93 body,94 })95 const bookData = await bookRes.json()96 return new Response(JSON.stringify(bookData), {97 status: bookRes.status,98 headers: { ...corsHeaders, 'Content-Type': 'application/json' },99 })100 } else if (action === 'track') {101 const bookingRef = url.searchParams.get('bookingRef')102 const trackRes = await fetch(`${baseUrl}/shipments/${bookingRef}/milestones`, { headers: authHeaders })103 const trackData = await trackRes.json()104 return new Response(JSON.stringify(trackData), {105 status: trackRes.status,106 headers: { ...corsHeaders, 'Content-Type': 'application/json' },107 })108 } else {109 return new Response(110 JSON.stringify({ error: 'Invalid action. Use: quote, book, or track' }),111 { status: 400, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }112 )113 }114 } catch (error) {115 return new Response(116 JSON.stringify({ error: error.message }),117 { status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }118 )119 }120})Pro tip: Edge Functions have a maximum execution time of 60 seconds. The polling loop in this Edge Function polls for up to 30 seconds — if Freightos carriers take longer to respond, reduce the polling attempts or implement a client-side polling approach where the frontend calls the Edge Function multiple times.
Expected result: Lovable deploys the Edge Function to Cloud. The function handles OAuth2 token acquisition, rate request submission, polling, booking, and tracking in a single serverless endpoint.
Build the freight rate comparison UI
Build the freight rate comparison UI
With the Edge Function deployed, ask Lovable to build a freight rate comparison component. This is the core UI of a Freightos integration — a form that collects cargo details and displays multiple carrier quotes in a comparison view. The Freightos rate request body requires: origin and destination port codes (UNLOCODE format, e.g., 'CNSHA' for Shanghai, 'USLAX' for Los Angeles), cargo type (LCL, FCL_20, FCL_40, AIR), commodity (general cargo, dangerous goods, temperature controlled), weight in kg, volume in CBM for ocean or dimensions for air, and required by date. Lovable will generate a TypeScript interface for the rate response and render each quote as a comparison card. For complex freight integrations involving dangerous goods classifications, temperature-controlled cargo, or multi-leg routing, RapidDev's team can help configure the Freightos API request structure to match your specific cargo types and trade lanes. Once the rate comparison UI is working in sandbox, test with representative cargo specifications matching your actual business use case before switching to production credentials.
Create a freight rate calculator form using the freightos-proxy Edge Function. Fields: origin UNLOCODE (e.g., CNSHA for Shanghai), destination UNLOCODE (e.g., USLAX for Los Angeles), cargo type (dropdown: LCL, FCL_20ft, FCL_40ft, Air Freight), total weight in kg, volume in CBM, and earliest ship date. On submit with action=quote, show a loading message 'Collecting carrier rates...' while the Edge Function polls for results. Display results as comparison cards: carrier logo placeholder, service name, total price in USD, transit days, and a Book button. Sort results by price ascending by default.
Paste this in Lovable chat
Pro tip: UNLOCODE port codes are the standard for Freightos — use a port code lookup table or a port autocomplete API to help users find codes. Common codes: CNSHA (Shanghai), USLAX (Los Angeles), NLRTM (Rotterdam), SGSIN (Singapore), DEHAM (Hamburg).
Expected result: A freight rate calculator form is visible in your Lovable preview. Submitting test cargo data shows a loading state while the Edge Function polls Freightos, then displays comparison cards with carrier options.
Common use cases
Freight rate calculator for B2B checkout
Add a freight rate calculator to your B2B ordering flow that shows buyers real LCL and FCL ocean freight costs plus air freight options based on their cargo dimensions and destination port. Buyers see multiple carrier options with transit times, allowing them to choose based on cost versus speed.
Create a freight rate calculator component that calls a freightos-proxy Edge Function. The form should have fields for origin port (with autocomplete), destination port, cargo type (LCL or FCL), weight in kg, volume in CBM, and required delivery date. On submit, call the Freightos WebCargo API to get rate quotes. Display results as a comparison table showing carrier name, service type, total price in USD, transit days, and estimated arrival date. Show a loading state while waiting for carrier responses.
Copy this prompt to try it in Lovable
Freight booking and shipment management dashboard
Allow users to book a freight shipment directly from a list of Freightos rate quotes. After selecting a carrier and rate, the Edge Function calls the Freightos Booking API to confirm the shipment and returns a booking confirmation number for tracking.
After my freight rate calculator displays results, add a Book Now button on each rate card. When clicked, call the freightos-proxy Edge Function to submit a booking via the Freightos WebCargo Booking API with the selected quote ID, shipper details, and cargo information. On successful booking, display a confirmation modal with the booking reference number and save it to the shipments table in Supabase. Show the booking status in a shipments dashboard page.
Copy this prompt to try it in Lovable
Live cargo tracking and milestone notifications
Build a shipment tracking page where users enter a Freightos booking reference and see real-time cargo tracking milestones — departure, in transit, arrived at destination, customs clearance, delivered. The Edge Function polls the Freightos Tracking API and formats events for display.
Create a cargo tracking page where users enter a Freightos booking reference number. Call the freightos-proxy Edge Function to fetch tracking milestones from the Freightos Tracking API. Display events as a timeline: vessel departure, port arrival, customs clearance, final delivery. Show the current status prominently at the top with expected delivery date. Poll for updates every 30 minutes and show a last-updated timestamp.
Copy this prompt to try it in Lovable
Troubleshooting
OAuth2 token request returns 401 or 'invalid_client' error
Cause: The FREIGHTOS_CLIENT_ID or FREIGHTOS_CLIENT_SECRET in Cloud Secrets is incorrect, or you're using sandbox credentials against the production token endpoint (or vice versa).
Solution: Verify the Client ID and Secret values in Cloud Secrets match exactly what's shown in your Freightos API dashboard. Check that FREIGHTOS_ENV is set to 'sandbox' if your credentials are from the sandbox environment. The sandbox token endpoint is api-sandbox.webcargo.co and the production endpoint is api.webcargo.co — using mismatched credentials and endpoints causes this error.
Rate request returns an empty quotes array even after polling completes
Cause: The origin-destination port pair you requested may not have carrier coverage in the Freightos network, or the cargo type and weight combination doesn't match available service offerings for that route.
Solution: Test with well-covered routes first (Shanghai CNSHA → Los Angeles USLAX for ocean LCL). Verify the port UNLOCODE codes are correct — an invalid UNLOCODE causes Freightos to return no quotes rather than an error. Check the Freightos developer documentation for the specific cargo type field values — 'LCL', 'FCL_20', 'FCL_40', and 'AIR' are common values but verify against the latest API spec.
Edge Function times out before receiving carrier quotes
Cause: Freight rate collection is asynchronous and some carriers take longer than 30 seconds to respond, exceeding the polling loop's timeout. Edge Functions also have a hard 60-second execution limit.
Solution: Split the quote flow into two Edge Function calls: a 'submit' action that creates the rate request and returns the request ID immediately, and a 'poll' action that checks the rate request status. Have the React frontend call 'poll' every 5 seconds with the request ID until results arrive or a 2-minute frontend timeout is reached. This avoids Edge Function execution limits.
Booking API returns 'quote expired' error when trying to book a selected rate
Cause: Freight rate quotes from Freightos have a short validity window (often 15-30 minutes). If the user spends too long reviewing options before clicking Book, the quote expires.
Solution: Display an expiry timer on each quote card using the validUntil timestamp from the Freightos rate response. Disable the Book button and show a 'Rate expired — refresh' message when the timer reaches zero. Add a 'Refresh Rates' button that re-submits the rate request with the same parameters.
Best practices
- Always display rate validity timers on quote cards — Freightos quotes expire quickly (15-30 minutes), and booking an expired quote wastes a user's time with a failed API call.
- Store successful rate requests and quotes in Supabase with the full response JSON — this provides a quote history for users and lets you analyze which routes and carriers your customers prefer over time.
- Implement a two-phase quoting UI: show partial results as carriers respond rather than waiting for all carriers to complete, since some carriers respond in 2 seconds while others take 20+ seconds.
- Validate UNLOCODE port codes on the client side before submitting rate requests — maintain a local lookup table of the 50-100 most common ports your customers use rather than hitting the API with invalid codes.
- For production use, cache the OAuth2 bearer token in Supabase KV storage with its TTL rather than fetching a new token on every Edge Function invocation — token fetches add 200-500ms latency per API call.
- Include commodity descriptions and HS codes in booking requests from the start, even if not required by the sandbox — customs authorities at destination ports require this information and missing it causes clearance delays.
- Test your integration with the full range of cargo types your customers will actually ship before launch — LCL, FCL, and air freight have different response patterns and field requirements in the Freightos API.
Alternatives
DHL Express is the better choice for single-carrier express parcel and small freight shipments where you want DHL's specific network rather than a multi-carrier comparison marketplace.
UPS API is more appropriate if your freight needs are primarily domestic US freight and ground shipping, where UPS has deeper service coverage than Freightos's carrier network.
FedEx is a better fit for express air freight on major US routes where FedEx's own network rates may be more competitive than going through a marketplace like Freightos.
Frequently asked questions
What is the difference between Freightos and DHL for shipping?
Freightos is a freight marketplace that compares rates from 50+ freight forwarders and carriers for bulk cargo — pallets, containers, and heavy air freight measured in CBM and tonnes. DHL Express is a single carrier focused on express parcel and small package delivery. Use Freightos when you're moving large quantities of goods by ocean container or air freight; use DHL when you're shipping individual packages or small shipments quickly across international borders.
Does Freightos support all global trade lanes?
Freightos has strongest coverage on the major global trade lanes: Asia-Pacific to North America, Europe to North America, and intra-Asia routes. Coverage on less-trafficked lanes (e.g., Africa, Central Asia, landlocked countries) varies by carrier and may return fewer or no quotes. Test your specific origin-destination combinations during development to confirm adequate carrier coverage before building a user-facing feature.
How long does it take to get freight rate quotes from Freightos?
Rate collection is asynchronous. Some carriers respond within 2-5 seconds, while others may take 20-30 seconds or longer. The Edge Function in this integration polls for up to 30 seconds before returning available results. A production implementation should consider showing partial results as they arrive rather than waiting for all carriers, since users see value in any quotes returned quickly while more continue loading.
Can I use Freightos to book actual shipments, or just compare rates?
Freightos WebCargo supports both rate comparison and actual booking. After selecting a quote, you can submit a booking through the Freightos API, which connects to the freight forwarder's system and returns a booking confirmation reference. The forwarder then handles the physical pickup, documentation, and carrier booking. This end-to-end capability is what distinguishes Freightos from simple rate aggregators.
Is Freightos API access free?
Freightos WebCargo API access is not free — it requires a commercial agreement with Freightos. Pricing is typically volume-based (per booking or per API call) and is negotiated as part of the API access approval process. Freightos provides a free sandbox environment for development and testing. Contact Freightos sales during the application process to understand pricing for your expected booking volume.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation