Back to Blog
TutorialMarch 13, 20269 min read

Building a Delivery ETA Dashboard: Compare Quick Commerce Speed

Build a dashboard that compares delivery times across 7 quick commerce platforms in real-time.

#delivery ETA#groupeta#dashboard#visualization

In the quick commerce wars, delivery speed is everything. When a customer is choosing between BlinkIt, Zepto, and Swiggy Instamart, the promise of "10-minute delivery" can make or break a sale. But how fast do these platforms actually deliver? And does it vary by location, time of day, or day of the week? In this tutorial, we will build a real-time delivery ETA dashboard that answers these questions by pulling live ETA data from all 7 quick commerce platforms using the QuickCommerce API.

Whether you are a consumer app helping users find the fastest delivery, a business analyst tracking competitor logistics, or just a curious developer, this dashboard gives you a single view of delivery speeds across the entire quick commerce landscape in India.

Supported Platforms

The groupeta endpoint supports all 7 quick commerce platforms available in the API. Each platform returns its current estimated delivery time for the given location. Some platforms like BlinkIt and Zepto focus on ultra-fast 10-minute delivery, while others like DMart and BigBasket offer scheduled slots.

Understanding the groupeta Endpoint

The groupeta endpoint queries delivery ETAs across multiple platforms in a single call. You provide latitude, longitude, and a list of platforms, and it returns the current delivery estimate for each platform at that location. The response includes the ETA in minutes, the delivery promise text (e.g. "Delivery in 8 minutes"), and whether the platform is currently serviceable at that location.

Let us start by making a groupeta call for a location in Koramangala, Bangalore, one of the best-served areas for quick commerce in India. You can test this yourself in the API Playground.

GET /api/v1/groupetaGet delivery ETAs for all 7 platforms at a Bangalore location
Request (cURL)
curl -X GET "https://api.quickcommerceapi.com/api/v1/groupeta?lat=12.9352&lng=77.6245&platforms=blinkit,zepto,swiggy,bigbasket,dmart,jiomart,minutes" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "x-geolocation-pincode: 560034"
Response (JSON)
{
  "location": {
    "lat": 12.9352,
    "lng": 77.6245,
    "pincode": "560034"
  },
  "platforms": {
    "blinkit": {
      "status": "success",
      "eta_minutes": 8,
      "eta_text": "Delivery in 8 minutes",
      "serviceable": true,
      "store_name": "Blinkit Koramangala"
    },
    "zepto": {
      "status": "success",
      "eta_minutes": 10,
      "eta_text": "10 min delivery",
      "serviceable": true,
      "store_name": "Zepto Cafe - Koramangala"
    },
    "swiggy": {
      "status": "success",
      "eta_minutes": 12,
      "eta_text": "Get it in 12 mins",
      "serviceable": true,
      "store_name": "Swiggy Instamart - Koramangala 5th Block"
    },
    "bigbasket": {
      "status": "success",
      "eta_minutes": 18,
      "eta_text": "Delivery in 15-20 min",
      "serviceable": true,
      "store_name": "bb now - Koramangala"
    },
    "dmart": {
      "status": "success",
      "eta_minutes": 45,
      "eta_text": "Delivery by 2:30 PM",
      "serviceable": true,
      "store_name": "DMart Ready - Koramangala"
    },
    "jiomart": {
      "status": "success",
      "eta_minutes": 60,
      "eta_text": "Delivery within 1 hour",
      "serviceable": true,
      "store_name": "JioMart Express"
    },
    "minutes": {
      "status": "success",
      "eta_minutes": 15,
      "eta_text": "In 15 minutes",
      "serviceable": true,
      "store_name": "Minutes - Koramangala"
    }
  },
  "credits_used": 7,
  "response_time_ms": 2341
}

Try it live in the API Playground →

ETA Comparison at a Glance

Here is how delivery ETAs compare at a Koramangala, Bangalore address during a typical afternoon. BlinkIt leads with an 8-minute estimate, while scheduled-delivery platforms like DMart and JioMart trade speed for lower prices. The sweet spot for most users is the 10-15 minute range where Zepto, Swiggy, and Minutes compete.

PlatformETADelivery PromiseServiceableType
BlinkIt8 minDelivery in 8 minutesYesUltra-fast
Zepto10 min10 min deliveryYesUltra-fast
Swiggy Instamart12 minGet it in 12 minsYesQuick
Minutes15 minIn 15 minutesYesQuick
BigBasket (bb now)18 minDelivery in 15-20 minYesQuick
DMart Ready45 minDelivery by 2:30 PMYesScheduled
JioMart60 minDelivery within 1 hourYesScheduled

Delivery ETA Comparison (Koramangala, Bangalore)

Quick Commerce Market Share (India 2025)

8 min

Fastest

BlinkIt avg

7

Platforms

Compared

7 credits

API Cost

All platforms

Real-time

Data

Live ETAs

ETA Dashboard Architecture

📍LocationLat/Lon + Pincode
QuickCommerce API/v1/groupeta
📊DashboardRecharts viz
🔔AlertsThreshold notify

Info

DMart, JioMart, and Minutes require the x-geolocation-pincode header for accurate ETA results. Without it, these platforms may return an error or inaccurate data. Always pass the pincode for the most reliable results.

Building the Dashboard UI

Let us build a React dashboard component that fetches ETA data and visualizes it using a horizontal bar chart with recharts. The component handles loading, errors, and sorts platforms by fastest delivery. We will also add color coding: green for under 10 minutes, amber for 10-20 minutes, and red for over 20 minutes.

ETADashboard.tsx — React + Recharts
import { useState, useEffect } from "react";
import { BarChart, Bar, XAxis, YAxis, Tooltip, Cell, ResponsiveContainer } from "recharts";

interface PlatformETA {
  status: string;
  eta_minutes: number;
  eta_text: string;
  serviceable: boolean;
  store_name: string;
}

interface ETAResponse {
  platforms: Record<string, PlatformETA>;
  credits_used: number;
}

const ALL_PLATFORMS = "blinkit,zepto,swiggy,bigbasket,dmart,jiomart,minutes";

const getColor = (eta: number) => {
  if (eta <= 10) return "#22c55e"; // green
  if (eta <= 20) return "#f59e0b"; // amber
  return "#ef4444";                 // red
};

const PLATFORM_LABELS: Record<string, string> = {
  blinkit: "BlinkIt",
  zepto: "Zepto",
  swiggy: "Swiggy",
  bigbasket: "BigBasket",
  dmart: "DMart",
  jiomart: "JioMart",
  minutes: "Minutes",
};

export default function ETADashboard() {
  const [data, setData] = useState<ETAResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [coords, setCoords] = useState({ lat: 12.9352, lng: 77.6245 });
  const [pincode, setPincode] = useState("560034");

  const fetchETA = async (lat: number, lng: number, pin: string) => {
    setLoading(true);
    try {
      const res = await fetch(
        `https://api.quickcommerceapi.com/api/v1/groupeta?lat=${lat}&lng=${lng}&platforms=${ALL_PLATFORMS}`,
        {
          headers: {
            "X-API-Key": process.env.NEXT_PUBLIC_QC_API_KEY!,
            "x-geolocation-pincode": pin,
          },
        }
      );
      setData(await res.json());
    } catch (err) {
      console.error("Failed to fetch ETA:", err);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchETA(coords.lat, coords.lng, pincode);
  }, [coords, pincode]);

  const chartData = data
    ? Object.entries(data.platforms)
        .filter(([_, v]) => v.serviceable)
        .map(([key, v]) => ({
          name: PLATFORM_LABELS[key] || key,
          eta: v.eta_minutes,
          text: v.eta_text,
        }))
        .sort((a, b) => a.eta - b.eta)
    : [];

  return (
    <div className="max-w-3xl mx-auto p-6">
      <h1 className="text-2xl font-bold mb-2">Delivery ETA Dashboard</h1>
      <p className="text-gray-500 mb-6">
        Real-time delivery estimates from 7 platforms at your location
      </p>

      {/* Location input */}
      <div className="flex gap-2 mb-6">
        <input
          value={pincode}
          onChange={(e) => setPincode(e.target.value)}
          placeholder="Pincode (e.g. 560034)"
          className="border rounded-lg px-4 py-2 w-40"
        />
        <button
          onClick={() => {
            navigator.geolocation.getCurrentPosition((pos) => {
              setCoords({ lat: pos.coords.latitude, lng: pos.coords.longitude });
            });
          }}
          className="bg-blue-600 text-white px-4 py-2 rounded-lg"
        >
          Use My Location
        </button>
      </div>

      {loading ? (
        <div className="text-center py-12 text-gray-400">Loading ETAs...</div>
      ) : (
        <>
          <ResponsiveContainer width="100%" height={chartData.length * 50 + 40}>
            <BarChart data={chartData} layout="vertical" margin={{ left: 80 }}>
              <XAxis type="number" domain={[0, "auto"]}
                label={{ value: "Minutes", position: "bottom" }} />
              <YAxis type="category" dataKey="name" width={80} />
              <Tooltip formatter={(val: number) => [`${val} min`, "ETA"]} />
              <Bar dataKey="eta" radius={[0, 6, 6, 0]}>
                {chartData.map((entry, i) => (
                  <Cell key={i} fill={getColor(entry.eta)} />
                ))}
              </Bar>
            </BarChart>
          </ResponsiveContainer>

          {/* Legend */}
          <div className="flex gap-4 mt-4 text-sm">
            <span className="flex items-center gap-1">
              <span className="w-3 h-3 rounded-full bg-green-500" /> Under 10 min
            </span>
            <span className="flex items-center gap-1">
              <span className="w-3 h-3 rounded-full bg-amber-500" /> 10-20 min
            </span>
            <span className="flex items-center gap-1">
              <span className="w-3 h-3 rounded-full bg-red-500" /> Over 20 min
            </span>
          </div>

          <p className="text-xs text-gray-400 mt-4 text-right">
            Credits used: {data?.credits_used}
          </p>
        </>
      )}
    </div>
  );
}

Adding Location Detection

For the best user experience, your dashboard should automatically detect the user's location. Here is a utility function that gets the user's coordinates from the browser and reverse geocodes to find the pincode. This ensures DMart, JioMart, and Minutes return accurate ETAs.

useLocation.ts — Custom Hook
import { useState, useEffect } from "react";

interface LocationState {
  lat: number;
  lng: number;
  pincode: string;
  city: string;
  loading: boolean;
  error: string | null;
}

export function useLocation() {
  const [location, setLocation] = useState<LocationState>({
    lat: 12.9716, lng: 77.5946, // Default: Bangalore
    pincode: "560001", city: "Bangalore",
    loading: true, error: null,
  });

  useEffect(() => {
    if (!navigator.geolocation) {
      setLocation((prev) => ({ ...prev, loading: false, error: "Geolocation not supported" }));
      return;
    }

    navigator.geolocation.getCurrentPosition(
      async (position) => {
        const { latitude, longitude } = position.coords;
        try {
          // Reverse geocode with a free service or Google Maps
          const res = await fetch(
            `https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=json`
          );
          const geo = await res.json();
          setLocation({
            lat: latitude,
            lng: longitude,
            pincode: geo.address?.postcode || "560001",
            city: geo.address?.city || geo.address?.town || "Unknown",
            loading: false,
            error: null,
          });
        } catch {
          setLocation({
            lat: latitude, lng: longitude,
            pincode: "560001", city: "Unknown",
            loading: false, error: null,
          });
        }
      },
      (err) => {
        setLocation((prev) => ({ ...prev, loading: false, error: err.message }));
      }
    );
  }, []);

  return location;
}

Delivery ETAs change throughout the day. During lunch and dinner rush, ETAs spike as delivery partners are stretched thin. By tracking ETAs at regular intervals, you can identify patterns like "BlinkIt is fastest before 11am but Zepto wins after 6pm" or "BigBasket ETAs double on weekends." This data is valuable for logistics teams, marketplace analysts, and apps that recommend the fastest platform at any given moment.

You can reuse the same cron-based approach from our price tracking guide to log ETAs to a database every 30 minutes. Combine this with a charting library to build a time-series ETA visualization.

Tip

The groupeta endpoint with all 7 platforms costs 7 credits per call. If you poll every 30 minutes for 24 hours, that is 336 credits per day. Consider reducing the platform list or polling frequency for cost efficiency. Check the pricing page for bulk credit options.

Get Started

1

Sign up for free

Create your account at quickcommerceapi.com/auth/signup. Get 50 free credits instantly.

2

Test groupeta in the Playground

Head to the API Playground and try a groupeta call with your coordinates. See how ETAs vary by location.

3

Build your dashboard

Use the React component above as a starting point. Install recharts with: npm install recharts

4

Add location detection

Integrate the useLocation hook for automatic location detection. Remember to pass the pincode header for DMart, JioMart, and Minutes.

5

Deploy and iterate

Deploy to Vercel or Netlify. Add features like ETA history, notifications for fast delivery windows, and multi-location comparison.

Try It Now

Want to see groupeta in action before building anything? The API Playground lets you make live API calls with your key and see real ETA data from your location.

What to Build Next

A delivery ETA dashboard pairs naturally with other QuickCommerce API features. Combine ETA data with price comparison to recommend the cheapest and fastest platform. Use market intelligence data to understand how delivery speed correlates with pricing strategy. Or check out our platform comparison guide for a deep dive into how each platform stacks up across every metric.

Info

The QuickCommerce API returns real-time data from live platforms. ETAs reflect actual current delivery estimates, not historical averages. Results will vary based on time of day, platform load, and local store availability.

Ready to Get Started?

Sign up for free and get 50 credits instantly. No credit card required. Start querying 7 quick commerce platforms with a single API.