Dealer territories
Route each buyer to the dealer whose territory they live in with Geocode AI boundaries, then show that dealer's stock.
A territory is a list of boundaries
Dealer groups, leasing desks and rental networks split a market by county, city or postcode. Store each territory as the ids of those boundaries rather than a hand-drawn polygon. Boundaries come from Geocode AI, also made by Meter. Searching by name is free and needs no key.
# free, no key: the county ids a territory is made of
curl "https://geocodeai.dev/v1/boundaries/search?q=Alameda%20County&country=US&kind=county"
# → results[0].id: "r396499" (Contra Costa County: r396462, Santa Clara County: r396501)Route the buyer, then show the stock
On your server, test the buyers' coordinates against each territory in one batch, then mint signed URLs for the matching dealer's vehicles. Both keys stay on the server; the page gets plain image URLs it can put in an img. Look each stock record up once to get its vehicle id (by VIN, see Dealer & VIN tools) and store it.
const GEOCODE = "https://geocodeai.dev";
const CAR_IMAGE = "https://carimage.dev";
/** Each dealer's territory, as Geocode AI boundary ids. */
const territories = {
"east-bay-motors": ["r396499", "r396462"], // Alameda + Contra Costa
"south-bay-auto": ["r396501"], // Santa Clara
};
/** Buyers as [lon, lat]; up to 10,000 per call, 1 Geocode unit per 1,000 points. */
export async function dealerFor(buyers: [number, number][]) {
const dealer: (string | null)[] = buyers.map(() => null);
for (const [name, ids] of Object.entries(territories)) {
for (const id of ids) {
const res = await fetch(`${GEOCODE}/v1/boundaries/${id}/contains`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.GEOCODE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ points: buyers }),
});
const { inside } = (await res.json()) as { inside: boolean[] };
inside.forEach((hit, i) => { if (hit) dealer[i] ??= name; });
}
}
return dealer; // null: no dealer covers that buyer
}
/** The dealer's stock as browser-safe image URLs: one vehicle image each, at creation. */
export async function stockImages(vehicleIds: string[]) {
const res = await fetch(`${CAR_IMAGE}/api/v1/image-urls`, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CAR_IMAGE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
images: vehicleIds.map((vehicle) => ({
vehicle, view: "front-3-4", width: 480, height: 320, trim: true, format: "auto",
})),
ttl_seconds: 604800,
renew: true,
}),
});
const { data } = (await res.json()) as { data: { url: string }[] };
return data.map((image) => image.url);
}
// stockImages(["veh_errc87t1jgata", "veh_395yw8tn73ff8"])Draw the territory
A dealer page with a map needs one shape, not three. Merge the territory's boundaries into one GeoJSON polygon and draw it with any map library. Cache it: county lines change rarely.
# one polygon for the dealer's map: Alameda + Contra Costa, 2 Geocode units
curl -X POST "https://geocodeai.dev/v1/boundaries/union" \
-H "Authorization: Bearer $GEOCODE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"include":["r396499","r396462"],"detail":"low"}'
# → a GeoJSON Feature with properties.area_km2: draw it under the dealer's pinsSigned URL lifetimes, renewal and billing are on Signed URLs; every Geocode AI operation and its cost is in the Geocode AI docs.