Skip to main content
RapidDev - Software Development Agency
bolt-ai-integrationsBolt Chat + API Route

How to Integrate Bolt.new with Freightos

Freightos integrates with Bolt.new through its WebCargo API to get real-time freight rate quotes for international shipments. Access requires a Freightos business account with API approval. Build a freight rate comparison dashboard using Next.js API routes to proxy authenticated requests — outbound API calls work in Bolt's WebContainer, but webhook callbacks for booking confirmations require deploying to Netlify or Bolt Cloud first.

What you'll learn

  • How to request and configure access to the Freightos WebCargo API for your Bolt.new application
  • How to build a freight rate comparison tool that queries multiple carriers via a single Freightos API request through Next.js
  • How to implement shipment booking and confirmation flows with proper webhook handling after deployment
  • How to display freight quotes with transit times, carrier names, and pricing in a React dashboard
  • Why Freightos API requires deployment for webhooks and how to test booking confirmations in production
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate21 min read25 minutesOtherApril 2026RapidDev Engineering Team
TL;DR

Freightos integrates with Bolt.new through its WebCargo API to get real-time freight rate quotes for international shipments. Access requires a Freightos business account with API approval. Build a freight rate comparison dashboard using Next.js API routes to proxy authenticated requests — outbound API calls work in Bolt's WebContainer, but webhook callbacks for booking confirmations require deploying to Netlify or Bolt Cloud first.

Building a Freight Rate Comparison Tool with Freightos in Bolt.new

Freightos is one of the largest digital freight marketplaces, processing billions of dollars in freight bookings annually. Its WebCargo platform connects shippers to hundreds of freight forwarders and carriers for international ocean, air, and land cargo. For businesses that need to programmatically compare freight rates across carriers, book shipments, and track cargo — and want to embed this functionality in their own application rather than navigating the Freightos marketplace UI — the WebCargo API provides a comprehensive HTTP interface.

The primary use case for a Bolt.new integration is building a custom freight procurement tool: an e-commerce platform that shows real-time shipping cost estimates to customers at checkout, a logistics dashboard for a business's operations team to compare carrier rates and book shipments, or a freight intelligence tool that tracks rate trends across lanes and carriers. The API returns quotes with carrier names, transit times, service types (door-to-door, port-to-port), and all-in rates including surcharges.

Important to understand before starting: the Freightos WebCargo API is designed for business customers, not individual developers. API access requires a Freightos business account and an application and approval process through their developer program or enterprise sales team. This is different from self-service developer APIs like Stripe or Plaid. If your project is at an early validation stage, consider using ShipPo or EasyPost APIs first — these cover parcel shipping (not freight) but are self-service and easier to prototype with. For actual international freight rate comparison at the cargo level, Freightos WebCargo is the right choice once you have business approval.

Integration method

Bolt Chat + API Route

Freightos integrates through its WebCargo API, which provides programmatic access to freight rate quotes, booking, and shipment tracking. API access requires approval through a Freightos business account — this is an enterprise-focused API, not a self-service developer tool. All API calls use HTTP and can be made from Next.js API routes in Bolt.new, keeping your API credentials server-side. Booking confirmation webhooks require a deployed public URL and cannot be received in Bolt's WebContainer preview.

Prerequisites

  • A Freightos business account at freightos.com — sign up as a business, not an individual, as the API is for commercial freight operations
  • Approved WebCargo API credentials (API key and secret) from Freightos — request API access through your Freightos account dashboard or their enterprise sales team
  • A Bolt.new project using Next.js for server-side API routes — Freightos API credentials must remain server-side to prevent unauthorized access
  • Understanding of freight terminology: incoterms (EXW, FOB, CIF, DAP), cargo measurements (CBM for volume, TEU for container equivalents), and port codes (UNLOCODE format)
  • A deployed URL on Netlify or Bolt Cloud for receiving Freightos webhook notifications about booking status updates — webhooks cannot be received in Bolt's WebContainer preview

Step-by-step guide

1

Set up Freightos WebCargo API access and credentials

Getting Freightos WebCargo API access requires working through their enterprise onboarding process rather than self-service signup. The steps differ depending on whether you are an existing Freightos customer or approaching them purely for API access. For businesses already using the Freightos marketplace: log into your Freightos account at app.freightos.com, navigate to Account Settings → API Access or Integrations. If your account plan includes API access, you can generate API credentials from the dashboard. Contact your Freightos account manager if the API option is not visible — they can enable it for your account tier. For new customers approaching Freightos specifically for the API: go to freightos.com and contact their enterprise or developer team. Explain your use case — the freight quote comparison tool, e-commerce integration, or logistics dashboard you are building. Freightos evaluates API applications based on business legitimacy and expected usage volume. Consumer apps or hobbyist projects are unlikely to be approved; legitimate business logistics integrations are the target customer. The WebCargo API uses API key authentication. Once approved, you receive an API key and an API secret (used together as Basic authentication credentials, base64 encoded). Store these as FREIGHTOS_API_KEY and FREIGHTOS_API_SECRET in your Bolt .env file. Never expose these in client-side code. Freightos provides a sandbox environment for approved partners that returns realistic test quotes without creating real bookings. The sandbox API base URL is typically https://sandbox.api.webcargo.co/v2 (verify the exact URL with Freightos at onboarding). The production API base is https://api.webcargo.co/v2. Use sandbox for all development in your Bolt project — only switch to production when you are ready to process real shipments. For simpler parcel shipping use cases (packages under 70kg / 150lbs) that do not require freight-level complexity, consider ShipPo (goshippo.com) or EasyPost (easypost.com) instead. Both have free developer sandboxes with self-service signup and cover major carriers (FedEx, UPS, DHL) for parcel rates and labels. The Freightos API specifically targets freight: full containers (FCL), less-than-container-load (LCL), air cargo (tons), and heavy road freight.

Bolt.new Prompt

Set up Freightos API configuration in this Next.js app. Add FREIGHTOS_API_KEY, FREIGHTOS_API_SECRET, and FREIGHTOS_API_ENV (sandbox or production) to .env with placeholder values. Create a lib/freightos/client.ts file that: (1) exports a freightosRequest(endpoint, method, body) utility function that calls the Freightos WebCargo API at the appropriate base URL, uses Basic auth (base64 of API_KEY:API_SECRET), sets Content-Type: application/json and Accept: application/json headers, handles errors with status codes, and returns parsed JSON. (2) Exports TypeScript interfaces for FreightosQuoteRequest (origin, destination, cargo), FreightosQuoteResult (carrier, price, currency, transitDays, serviceType), and FreightosBookingRequest. Add API base URL constants for sandbox and production.

Paste this in Bolt.new chat

lib/freightos/client.ts
1// lib/freightos/client.ts
2export const FREIGHTOS_API_BASE =
3 process.env.FREIGHTOS_API_ENV === 'production'
4 ? 'https://api.webcargo.co/v2'
5 : 'https://sandbox.api.webcargo.co/v2';
6
7function getAuthHeader(): string {
8 const key = process.env.FREIGHTOS_API_KEY ?? '';
9 const secret = process.env.FREIGHTOS_API_SECRET ?? '';
10 return `Basic ${Buffer.from(`${key}:${secret}`).toString('base64')}`;
11}
12
13export async function freightosRequest<T>(
14 endpoint: string,
15 method: 'GET' | 'POST' | 'PUT' = 'GET',
16 body?: object
17): Promise<T> {
18 const response = await fetch(`${FREIGHTOS_API_BASE}${endpoint}`, {
19 method,
20 headers: {
21 Authorization: getAuthHeader(),
22 'Content-Type': 'application/json',
23 Accept: 'application/json',
24 },
25 body: body ? JSON.stringify(body) : undefined,
26 });
27
28 if (!response.ok) {
29 const error = await response.text().catch(() => response.statusText);
30 throw new Error(`Freightos API ${response.status}: ${error}`);
31 }
32
33 return response.json();
34}
35
36// TypeScript interfaces for Freightos API
37export interface FreightosCargoDetails {
38 weight: { value: number; unit: 'kg' | 'lbs' };
39 volume?: { value: number; unit: 'cbm' | 'cft' };
40 containerType?: 'LCL' | '20GP' | '40GP' | '40HC';
41 commodity?: string;
42}
43
44export interface FreightosQuoteRequest {
45 origin: { port: string; country: string };
46 destination: { port: string; country: string };
47 cargo: FreightosCargoDetails;
48 incoterms: 'EXW' | 'FOB' | 'CIF' | 'DAP' | 'DDP';
49 shipmentDate: string; // YYYY-MM-DD
50}
51
52export interface FreightosQuoteResult {
53 quoteId: string;
54 carrier: string;
55 serviceType: string;
56 price: { total: number; currency: string };
57 transitDays: { min: number; max: number };
58 validUntil: string;
59 serviceLevel: 'standard' | 'express' | 'economy';
60}

Pro tip: Port codes in the Freightos API use UNLOCODE format (e.g., CNSHA for Shanghai, USLAX for Los Angeles). Find UNLOCODE values at unece.org/trade/cefact/unlocode-code-list-country-and-territory. Country codes use ISO 3166-1 alpha-2 format (CN, US, DE, etc.).

Expected result: The Freightos client utility is configured with credential management and API base URL selection. The TypeScript interfaces provide type safety for quote requests and responses. The .env file has placeholder credentials ready for your Freightos-provided keys.

2

Build the freight rate comparison API route and UI

The core of the Freightos integration is the rate quote flow: the user enters shipment details (origin, destination, cargo), your Next.js API route calls the Freightos quotes endpoint, and the results are displayed as a comparison table of available freight options sorted by price or transit time. The Freightos quotes API call requires careful input formatting. Origins and destinations are specified as port codes (UNLOCODE format) or city/country pairs depending on the shipment type. FCL (full container load) and LCL (less-than-container-load) ocean freight uses port-to-port UNLOCODE codes. Air freight uses IATA airport codes. The cargo specification includes weight, volume, and for FCL, the container type. The API response returns an array of quote objects, each representing a different carrier or service option. Key fields to display are: carrier name, total price (with currency), transit time range (minimum and maximum days), service type (standard, express, economy), the route (which ports are included), and a quote validity date. The quote ID is critical — you need it to proceed with booking. Sort the results by total price by default, with options to sort by transit time or carrier. Highlight the fastest option and the cheapest option with visual badges. For LCL shipments, show the per-CBM rate alongside the total rate so users can compare across different cargo sizes. The frontend form needs fields for: origin port (UNLOCODE or city), destination port, shipment date, incoterms (dropdown), cargo type (LCL/FCL/Air), weight (kg), and volume (CBM for ocean, kg for air). Add a 'Calculate Rates' button that triggers the API call. Show a loading state while the quote request is processing — Freightos queries multiple carriers in real time, so responses can take 2-5 seconds. Critical note for the Bolt WebContainer context: the API route makes an outbound HTTPS call to Freightos, which works fine in the WebContainer. There are no native module dependencies, no TCP socket requirements. The Freightos API is pure HTTP — a perfect fit for Bolt's architecture. The only limitation is webhook callbacks for booking confirmations, which require a deployed public URL.

Bolt.new Prompt

Build a freight rate comparison feature. Create an API route at app/api/freight/rates/route.ts that accepts a POST request with { origin, destination, cargo, incoterms, shipmentDate } and calls the Freightos WebCargo quotes endpoint using the freightosRequest utility from lib/freightos/client.ts. Return quotes sorted by total price. Build a rates comparison page at app/freight/page.tsx with: (1) A form with inputs for origin port (UNLOCODE), destination port, cargo weight (kg), cargo volume (CBM), container type dropdown (LCL/20GP/40GP), incoterms dropdown, and shipment date picker. (2) A results section showing each quote as a card with carrier name, service type, total price, transit time range, and a 'Select & Book' button. (3) Sort buttons for 'Cheapest First' and 'Fastest First'. Show loading spinner while fetching. Use Tailwind CSS.

Paste this in Bolt.new chat

app/api/freight/rates/route.ts
1// app/api/freight/rates/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { freightosRequest, type FreightosQuoteRequest, type FreightosQuoteResult } from '@/lib/freightos/client';
4
5export async function POST(request: NextRequest) {
6 try {
7 const body = await request.json() as FreightosQuoteRequest;
8
9 // Validate required fields
10 if (!body.origin?.port || !body.destination?.port) {
11 return NextResponse.json(
12 { error: 'Origin and destination port codes are required' },
13 { status: 400 }
14 );
15 }
16 if (!body.cargo?.weight?.value) {
17 return NextResponse.json(
18 { error: 'Cargo weight is required' },
19 { status: 400 }
20 );
21 }
22
23 const quotes = await freightosRequest<{ quotes: FreightosQuoteResult[] }>(
24 '/quotes',
25 'POST',
26 body
27 );
28
29 // Sort by total price by default
30 const sorted = quotes.quotes.sort(
31 (a, b) => a.price.total - b.price.total
32 );
33
34 // Tag the cheapest and fastest options
35 const cheapestId = sorted[0]?.quoteId;
36 const fastestId = [...sorted].sort(
37 (a, b) => a.transitDays.min - b.transitDays.min
38 )[0]?.quoteId;
39
40 const enriched = sorted.map((q) => ({
41 ...q,
42 isCheapest: q.quoteId === cheapestId,
43 isFastest: q.quoteId === fastestId,
44 }));
45
46 return NextResponse.json({ quotes: enriched, total: enriched.length });
47 } catch (error) {
48 const message = error instanceof Error ? error.message : 'Failed to fetch freight rates';
49 // Check for auth errors
50 if (message.includes('401') || message.includes('403')) {
51 return NextResponse.json(
52 { error: 'Freightos API authentication failed — verify FREIGHTOS_API_KEY and FREIGHTOS_API_SECRET' },
53 { status: 401 }
54 );
55 }
56 return NextResponse.json({ error: message }, { status: 500 });
57 }
58}

Pro tip: Common UNLOCODE pairs to use for testing in sandbox: CNSHA (Shanghai) → USLAX (Los Angeles) for transpacific ocean, DEHAM (Hamburg) → USJFK (New York) for transatlantic, CNPVG (Shanghai Pudong Airport) → USORD (Chicago O'Hare) for air freight.

Expected result: The freight rates form accepts shipment details and returns a list of carrier quotes sorted by price. The cheapest and fastest options are visually tagged. The loading spinner shows while Freightos queries real-time carrier rates (2-5 seconds in production).

3

Implement freight booking and webhook handling

After selecting a quote, the user confirms booking through the Freightos API. The booking request references the quote ID from the rate comparison and adds shipper and consignee details (company names, addresses, contact information). The Freightos API validates the information, reserves the slot with the carrier, and returns a booking reference number. The booking flow requires more information than the rate quote: full shipper company name and address, consignee company name and address, commodity description for customs, Harmonized System (HS) code for the goods, total invoice value and currency for customs declaration, and the number of packages with dimensions if not a full container. Store bookings in a Supabase table after each successful booking API call. The minimum fields to store are: the Freightos booking reference, quote ID, carrier name, origin and destination, status, cargo details, and timestamps. This gives you a local record of all freight bookings even if the Freightos API is temporarily unavailable. Freightos sends webhook notifications when booking status changes: booking confirmed by carrier, documents available (bill of lading), in-transit updates, customs clearance, and delivery confirmation. Register your webhook URL in the Freightos dashboard after deploying your app — webhooks cannot be received in Bolt's WebContainer since it has no public URL. The webhook handler at /api/freight/webhooks/freightos receives POST requests from Freightos with event type and booking data. Verify the request authenticity using the signature header Freightos includes (check the exact header name and signature algorithm in your Freightos documentation — it varies by integration type). After verification, update the booking status in your Supabase database and trigger any downstream actions (send shipment update email, notify ops team via Slack, update customer order status). For development testing without webhook functionality, you can poll the Freightos GET /bookings/{id} endpoint to check booking status updates instead of waiting for webhooks. This works in the Bolt WebContainer and is sufficient for validating the booking flow before deploying.

Bolt.new Prompt

Build a freight booking flow. Create a Supabase table 'freight_bookings' with columns: id uuid pk, user_id uuid references auth.users(id), freightos_booking_ref text, quote_id text, carrier text, origin text, destination text, status text default 'pending', cargo_details jsonb, total_cost decimal, currency text, booked_at timestamptz default now(). Create an API route at app/api/freight/book/route.ts that accepts shipper details, consignee details, and the quote ID from the selected rate, POSTs to the Freightos booking endpoint, saves the booking to Supabase, and returns the booking reference. Create a webhook handler at app/api/freight/webhooks/freightos/route.ts that accepts POST requests, verifies the Freightos signature header, and updates the booking status in Supabase. Add a comment that webhooks only fire after deployment.

Paste this in Bolt.new chat

app/api/freight/webhooks/freightos/route.ts
1// app/api/freight/webhooks/freightos/route.ts
2// NOTE: Freightos webhooks only fire after deployment to Netlify or Bolt Cloud.
3// Bolt's WebContainer has no public URL — Freightos cannot deliver events to it.
4// To test booking status during development, poll GET /api/freight/booking/{id} instead.
5import { NextRequest, NextResponse } from 'next/server';
6import crypto from 'crypto';
7import { createClient } from '@/lib/supabase/server';
8
9function verifyFreightosSignature(secret: string, signature: string, body: string): boolean {
10 // Verify using HMAC-SHA256 — confirm exact algorithm with Freightos documentation
11 const expectedSig = crypto
12 .createHmac('sha256', secret)
13 .update(body)
14 .digest('hex');
15 try {
16 return crypto.timingSafeEqual(
17 Buffer.from(signature, 'hex'),
18 Buffer.from(expectedSig, 'hex')
19 );
20 } catch {
21 return false;
22 }
23}
24
25interface FreightosWebhookEvent {
26 eventType: 'booking.confirmed' | 'booking.in_transit' | 'booking.delivered' | 'booking.cancelled';
27 bookingReference: string;
28 updatedAt: string;
29 details?: Record<string, unknown>;
30}
31
32export async function POST(request: NextRequest) {
33 const webhookSecret = process.env.FREIGHTOS_WEBHOOK_SECRET;
34 if (!webhookSecret) {
35 return NextResponse.json({ error: 'Webhook secret not configured' }, { status: 500 });
36 }
37
38 const rawBody = await request.text();
39 const signature = request.headers.get('X-Freightos-Signature') ?? '';
40
41 if (signature && !verifyFreightosSignature(webhookSecret, signature, rawBody)) {
42 return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
43 }
44
45 const event: FreightosWebhookEvent = JSON.parse(rawBody);
46 const supabase = await createClient();
47
48 const statusMap: Record<FreightosWebhookEvent['eventType'], string> = {
49 'booking.confirmed': 'confirmed',
50 'booking.in_transit': 'in_transit',
51 'booking.delivered': 'delivered',
52 'booking.cancelled': 'cancelled',
53 };
54
55 const newStatus = statusMap[event.eventType] ?? 'unknown';
56
57 await supabase
58 .from('freight_bookings')
59 .update({ status: newStatus })
60 .eq('freightos_booking_ref', event.bookingReference);
61
62 console.log(`Freightos webhook: ${event.eventType} for booking ${event.bookingReference}`);
63
64 return NextResponse.json({ received: true });
65}

Pro tip: After deploying your app, register the webhook URL in your Freightos dashboard by going to Account Settings → Webhook Configuration and entering https://yourapp.netlify.app/api/freight/webhooks/freightos. Use Freightos's webhook test feature to send a test event and verify your handler logs the correct booking reference.

Expected result: After deploying and registering the webhook URL, Freightos sends POST requests to the handler when bookings change status. The Supabase freight_bookings table updates automatically. Server logs show received webhook events with booking references and status changes.

4

Build the freight tracking dashboard

The freight tracking dashboard brings together all booked shipments and their current status. Operations teams use this view to monitor in-progress shipments, identify delays, and get visibility across all active freight lanes. The dashboard queries your Supabase freight_bookings table for all bookings by the current user or organization. Display them in a table showing booking reference, carrier, route (origin → destination), status badge (color-coded: pending = yellow, confirmed = blue, in_transit = orange, delivered = green, cancelled = gray), cargo details, cost, and booking date. Sort by most recent bookings first. For each confirmed or in-transit booking, add a 'Track Shipment' button that calls the Freightos tracking API: GET /shipments/{bookingReference}/tracking. This returns a list of tracking events (departed origin port, arrived transshipment port, customs clearance, arrived destination port, etc.) with timestamps and locations. Display these as a timeline on a shipment detail page. Carrier-level tracking data is available for some carriers through Freightos but varies by carrier and service type. When carrier tracking is available, Freightos returns real vessel position data including ETA updates. When only carrier milestones are available (not real-time position), display the milestone events as the tracking timeline. For the operations manager view, add summary metrics at the top of the dashboard: total active shipments, shipments in-transit, shipments delivered this month, average transit time, and total freight spend this month. Calculate these from your Supabase bookings table using aggregation queries rather than real-time Freightos API calls — the local data is sufficient for summary metrics and does not consume API rate limit quota. For customers who want real-time tracking updates without refreshing the page, use Supabase Realtime to subscribe to changes in the freight_bookings table. When the webhook handler updates a booking's status, Supabase broadcasts the change to all subscribed clients — the dashboard updates automatically without a page refresh.

Bolt.new Prompt

Build a freight tracking dashboard at app/freight/dashboard/page.tsx. It should: (1) Fetch all the current user's freight bookings from Supabase, ordered by booked_at descending, (2) Show summary cards at the top: total bookings, in-transit count, delivered this month, (3) Display bookings in a table with columns: booking ref, carrier, origin → destination, status badge, cargo (from cargo_details.containerType), cost, and booking date, (4) Add a 'Track' button for confirmed/in-transit bookings that opens a side panel showing tracking events fetched from /api/freight/tracking/{ref}, (5) Add a Supabase Realtime subscription so the table status badges update automatically when webhooks update booking status. Use Tailwind CSS and shadcn/ui Table and Badge components.

Paste this in Bolt.new chat

app/api/freight/tracking/[ref]/route.ts
1// app/api/freight/tracking/[ref]/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3import { freightosRequest } from '@/lib/freightos/client';
4
5interface TrackingEvent {
6 timestamp: string;
7 location: string;
8 description: string;
9 eventType: string;
10}
11
12interface FreightosTrackingResponse {
13 bookingReference: string;
14 currentStatus: string;
15 estimatedDelivery?: string;
16 events: TrackingEvent[];
17}
18
19export async function GET(
20 _request: NextRequest,
21 { params }: { params: Promise<{ ref: string }> }
22) {
23 const { ref } = await params;
24
25 if (!ref) {
26 return NextResponse.json({ error: 'Booking reference required' }, { status: 400 });
27 }
28
29 try {
30 const tracking = await freightosRequest<FreightosTrackingResponse>(
31 `/shipments/${encodeURIComponent(ref)}/tracking`
32 );
33
34 return NextResponse.json({
35 bookingReference: tracking.bookingReference,
36 currentStatus: tracking.currentStatus,
37 estimatedDelivery: tracking.estimatedDelivery,
38 events: tracking.events.sort(
39 (a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
40 ),
41 });
42 } catch (error) {
43 const message = error instanceof Error ? error.message : 'Tracking unavailable';
44 return NextResponse.json({ error: message }, { status: 500 });
45 }
46}

Pro tip: Use Supabase Realtime for the dashboard's status auto-update rather than polling the Freightos API. Set up a channel subscription on the freight_bookings table: supabase.channel('freight').on('postgres_changes', { event: 'UPDATE', schema: 'public', table: 'freight_bookings' }, handler).subscribe(). This updates the dashboard instantly when webhooks change booking status.

Expected result: The freight dashboard shows all booked shipments with status badges that update automatically via Supabase Realtime. Clicking 'Track' on an in-transit shipment shows a timeline of tracking events including departure, transshipment, and estimated arrival. Summary metrics show total spend and active shipment counts.

Common use cases

Freight Rate Comparison Dashboard

An internal logistics tool for a business that queries real-time freight rates from multiple carriers for standard trade lanes (e.g., Shanghai to Los Angeles, 20ft container). The dashboard shows quotes from different freight forwarders with transit times, service types, and total costs, allowing procurement teams to compare and select the best option.

Bolt.new Prompt

Build a freight rate comparison dashboard. Create a Next.js API route at /api/freight/rates that accepts a POST request with origin (port or city), destination (port or city), cargo details (weight, volume, container type), and incoterms. Call the Freightos WebCargo API at https://api.webcargo.co/v2/quotes with FREIGHTOS_API_KEY and FREIGHTOS_API_SECRET from process.env as Basic auth. Return the quotes list with carrier name, total cost, currency, transit time, and service type. Build a form for entering shipment details and display results as sortable cards showing price, carrier, and transit time. Use Tailwind CSS.

Copy this prompt to try it in Bolt.new

E-commerce Checkout Freight Cost Estimator

A checkout step in an e-commerce store that calculates real-time freight shipping costs for B2B orders with large or heavy items. When the customer enters their destination country and order dimensions, the app queries Freightos for available rates and lets the customer select their preferred shipping option before placing the order.

Bolt.new Prompt

Add a freight cost estimator to the checkout flow. When the customer enters their shipping address and the order has dimensions over 150kg or 1 CBM, show a 'Get Freight Rates' section. Create an API route at /api/checkout/freight-rates that calls the Freightos rates API with the origin warehouse address, customer destination, and cargo dimensions (weight in kg, volume in CBM). Display the top 3 rate options as radio buttons showing carrier, estimated transit time, and price. Store the selected freight option in the order form state. Use the form shipping address data for the destination.

Copy this prompt to try it in Bolt.new

Freight Booking and Tracking System

A complete freight management system where users can request quotes, book shipments through the Freightos API, and track booked shipments. After booking, Freightos sends webhook updates for shipment milestones (confirmed, in transit, arrived). The webhook handler is registered after deploying the Bolt app — it cannot be received in the WebContainer preview.

Bolt.new Prompt

Build a freight booking system. Create three API routes: (1) /api/freight/quote to get rates from Freightos, (2) /api/freight/book to submit a booking for a selected quote using the quote ID and shipper/consignee details, (3) /api/freight/webhooks/freightos to handle POST webhook events from Freightos for shipment status updates (booked, confirmed, in transit, delivered). Store bookings in a Supabase table with columns: id, quote_id, booking_reference, status, origin, destination, carrier, cost, created_at. Add a comment that the webhook endpoint only receives events after deployment to Netlify or Bolt Cloud.

Copy this prompt to try it in Bolt.new

Troubleshooting

Freightos API returns 401 or 403 when querying freight rates

Cause: The API key and secret are incorrect, credentials are for the wrong environment (sandbox vs production), or API access has not been approved yet for your Freightos account.

Solution: Verify FREIGHTOS_API_KEY and FREIGHTOS_API_SECRET match exactly what Freightos provided — these are case-sensitive. Check that FREIGHTOS_API_ENV matches the environment your credentials are provisioned for ('sandbox' for testing, 'production' for live). If credentials are correct but access is still denied, contact your Freightos account manager — API access requires explicit provisioning and may not be active even with valid credentials if the account activation step was not completed.

typescript
1// Debug auth by logging the Authorization header format (not the actual values in production)
2const key = process.env.FREIGHTOS_API_KEY ?? '';
3const secret = process.env.FREIGHTOS_API_SECRET ?? '';
4console.log('Auth configured:', key.length > 0 && secret.length > 0);
5console.log('API env:', process.env.FREIGHTOS_API_ENV ?? 'sandbox');
6// Expected: Basic base64(apiKey:apiSecret)
7const auth = Buffer.from(`${key}:${secret}`).toString('base64');

Freight rate quotes return empty results or no available carriers for the specified route

Cause: The origin and destination UNLOCODE values may be incorrect or not supported by available carriers, the shipment date is too far in the future or past the booking window, the cargo dimensions exceed carrier limits, or the incoterms selected are not supported for the specified route.

Solution: Verify UNLOCODE values using the UN/LOCODE Code List at unece.org. Use major port codes for initial testing (CNSHA for Shanghai, USLAX for Los Angeles, DEHAM for Hamburg). Ensure the shipment date is at least 5 business days in the future — near-term requests often return fewer options. Check that cargo weight and volume are within reasonable freight ranges (LCL: 1-15 CBM, FCL: 20GP or 40GP containers). Try FOB or CIF incoterms first — these are the most widely supported.

typescript
1// Test with known-good trade lane values
2const testRequest = {
3 origin: { port: 'CNSHA', country: 'CN' },
4 destination: { port: 'USLAX', country: 'US' },
5 cargo: { weight: { value: 1000, unit: 'kg' }, volume: { value: 5, unit: 'cbm' }, containerType: 'LCL' },
6 incoterms: 'FOB',
7 shipmentDate: new Date(Date.now() + 14 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
8};

Freightos webhooks are not being received after registering the webhook URL in the dashboard

Cause: The app is receiving webhooks in Bolt's WebContainer preview which has no stable public URL, the webhook URL was registered before deployment, or the webhook signature verification is failing causing your handler to silently reject events.

Solution: Ensure you registered the webhook URL using your deployed app URL (e.g., https://yourapp.netlify.app/api/freight/webhooks/freightos), not the Bolt preview URL. After registering, use the Freightos dashboard's 'Send Test Event' feature to verify delivery. If test events are not appearing in your server logs, temporarily remove signature verification and log the raw request body to confirm events are arriving. Re-add verification once the basic connectivity is confirmed.

typescript
1// Temporarily skip signature check during debugging (re-add for production)
2export async function POST(request: NextRequest) {
3 const rawBody = await request.text();
4 console.log('Freightos webhook received:', rawBody.substring(0, 200));
5 // Parse and process without signature check during debugging
6 const event = JSON.parse(rawBody);
7 console.log('Event type:', event.eventType, 'Ref:', event.bookingReference);
8 return NextResponse.json({ received: true });
9}

Best practices

  • Cache freight rate quotes for 30-60 minutes client-side using the quote's validUntil timestamp — rate requests are expensive API calls, and users often refresh pages or navigate between steps without needing fresh quotes
  • Store all booking requests and responses in Supabase regardless of webhook status — this provides audit trail, enables status polling as a webhook fallback, and gives you local data for analytics without consuming Freightos API quota
  • Always validate cargo details (weight, volume, container type) before calling the Freightos API — invalid cargo dimensions cause API errors that are confusing for users; client-side validation gives instant feedback
  • Display the quote validity date prominently in the UI — Freightos quotes expire (typically 24-72 hours), and users should know they need to book before the quote expires to lock in the displayed rate
  • For webhook handling, respond with 200 immediately and process the event asynchronously — Freightos may retry if your handler takes too long to respond; use a queue or background task for database updates and downstream notifications
  • Use Supabase Realtime for dashboard status updates instead of polling the Freightos API — Supabase broadcasts database changes in real time when webhooks update booking status, and it is free within Supabase's usage limits
  • For development testing without deployed webhooks, add a 'Refresh Status' button that polls GET /api/freight/booking/{ref} which calls the Freightos tracking endpoint — this works in the Bolt WebContainer and validates your tracking logic before dealing with webhook setup

Alternatives

Frequently asked questions

How do I get access to the Freightos API for my Bolt.new app?

Freightos API access requires approval through their enterprise onboarding process. Go to freightos.com and contact their enterprise or developer team to explain your use case. Existing Freightos marketplace customers can request API access through their account dashboard under Settings → API Access. The approval process evaluates your business use case and expected shipment volume — this is not a self-service developer API, so expect a sales conversation before receiving credentials.

Can I test Freightos integration in Bolt.new's WebContainer preview?

Outbound API calls to Freightos's quote and tracking endpoints work in the Bolt WebContainer since they are standard HTTPS requests from Next.js API routes. You can query rates, retrieve tracking data, and test the booking flow in the preview. The only feature that cannot work in the preview is receiving Freightos webhook notifications — webhooks require a publicly accessible HTTPS URL, which the WebContainer does not have. Deploy to Netlify or Bolt Cloud to register and test webhooks.

What is the difference between Freightos and DHL or FedEx APIs?

Freightos is a freight marketplace that compares rates across many carriers simultaneously — one API call returns quotes from multiple freight forwarders and carriers. DHL and FedEx are single-carrier APIs that return rates only for their own services. Freightos focuses on international cargo freight (ocean containers, air cargo tons, heavy road freight), while DHL and FedEx APIs are stronger for express parcel delivery. Use Freightos when you need carrier-agnostic rate comparison for shipments over 150kg or 1 CBM.

Does Freightos require deployment to work with Bolt.new?

The rate quote and tracking API calls work in Bolt's WebContainer preview — these are outbound HTTPS requests that work fine. You only need deployment for Freightos webhooks, which send booking confirmation and status update notifications to a publicly accessible URL. For development, you can poll the tracking endpoint to check booking status without needing webhooks. Deploy to Netlify or Bolt Cloud when you need real-time status notifications in production.

Can I use Freightos for parcel shipping alongside DHL or FedEx?

Freightos specializes in international freight (cargo too large for standard parcel carriers), not parcel shipping. For mixed shipping needs — parcels under 70kg and freight over 150kg — integrate both Freightos (for freight) and a parcel carrier API like DHL, FedEx, or ShipStation (for parcels). Route the shipping quote request to the appropriate API based on the package weight and dimensions: below 70kg goes to parcel carriers, above 150kg goes to Freightos.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help with your project?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.