fetch API.
Quick start
const BHUMI_API_KEY = process.env.BHUMI_API_KEY!;
const BASE_URL = "https://api.bhumifarms.co";
async function bhumiGet<T = any>(
endpoint: string,
params?: Record<string, string | number>
): Promise<T> {
const url = new URL(`${BASE_URL}${endpoint}`);
if (params) {
Object.entries(params).forEach(([k, v]) =>
url.searchParams.set(k, String(v))
);
}
const res = await fetch(url, {
headers: { "X-API-Key": BHUMI_API_KEY },
});
if (!res.ok) {
const error = await res.json();
throw new Error(`${error.error.code}: ${error.error.message}`);
}
return res.json();
}
// Search farms near Portland
const { data, meta } = await bhumiGet("/v1/search", {
lat: 45.52,
lng: -122.68,
radius: 25,
products: "raw milk,eggs",
});
data.forEach((farm) => {
console.log(`${farm.name} — ${farm.distance_mi}mi`);
});
With Next.js (server component)
// app/farms/page.tsx
export default async function FarmsPage() {
const res = await fetch(
"https://api.bhumifarms.co/v1/search?lat=45.52&lng=-122.68&radius=25",
{
headers: { "X-API-Key": process.env.BHUMI_API_KEY! },
next: { revalidate: 300 }, // Cache for 5 minutes
}
);
const { data } = await res.json();
return (
<ul>
{data.map((farm) => (
<li key={farm.id}>{farm.name} — {farm.distance_mi}mi</li>
))}
</ul>
);
}
Pagination helper
async function getAllFarms(state: string) {
const farms = [];
let page = 1;
let hasMore = true;
while (hasMore) {
const result = await bhumiGet("/v1/farms", {
state,
page,
per_page: 100,
});
farms.push(...result.data);
hasMore = result.meta.has_more;
page++;
}
return farms;
}
Error handling
try {
const farm = await bhumiGet("/v1/farms/invalid-id");
} catch (err) {
console.error(err.message);
// NOT_FOUND: Farm not found.
}