Developers

Examples

Copy-paste integration patterns for the Mungfali Image Search API — from your first curl to production server-side proxies.

All examples use https://mungfali.net/v1/search. Replace YOUR_API_KEY or $MUNGFALI_API_KEY with a key from Dashboard → API Keys.

Common scenarios

Basic keyword search

Return up to twenty images for a simple query. Parse value[].imageUrl for display.

GET /v1/search?q=mountains&count=20

bash
curl -s "https://mungfali.net/v1/search?q=car&count=10" \
  -H "X-API-Key: $MUNGFALI_API_KEY"

Family-friendly results

Use safesearch=strict for consumer apps, education, or kid-focused products.

GET /v1/search?q=family+picnic&safesearch=strict&count=30

bash
curl -s "https://mungfali.net/v1/search?q=family+picnic&safesearch=strict&count=30" \
  -H "X-API-Key: $MUNGFALI_API_KEY"

Domain and transparency filters

Limit to a trusted source and exclude transparent PNGs for consistent card layouts.

GET /v1/search?q=logo&transparent=true&site=pexels.com

bash
curl -s "https://mungfali.net/v1/search?q=logo&transparent=true&site=pexels.com" \
  -H "X-API-Key: $MUNGFALI_API_KEY"

Server-side proxy (recommended)

Never expose API keys in browser code. Call Mungfali from your backend and return URLs to the client.

Your API → GET /v1/search → Mungfali

bash
// pages/api/images.js (Next.js example)
export default async function handler(req, res) {
  const q = req.query.q;
  const upstream = await fetch(
    `https://mungfali.net/v1/search?q=${encodeURIComponent(q)}&count=24`,
    { headers: { 'X-API-Key': process.env.MUNGFALI_API_KEY } }
  );
  res.status(upstream.status).json(await upstream.json());
}

Language examples

JavaScript / Node.js

Use fetch (Node 18+) or any HTTP client. Handle non-2xx responses before parsing JSON.

javascript
const res = await fetch(
  'https://mungfali.net/v1/search?q=car&count=50',
  { headers: { 'X-API-Key': process.env.MUNGFALI_API_KEY } }
);

if (!res.ok) {
  const err = await res.json().catch(() => ({}));
  throw new Error(err.error || res.statusText);
}

const data = await res.json();
console.log(data.name);           // "car"
console.log(data.value[0].imageUrl);

Python

Install requests (pip install requests) and pass parameters via params.

python
import os
import requests

response = requests.get(
    'https://mungfali.net/v1/search',
    params={'q': 'car', 'count': 50, 'safesearch': 'moderate'},
    headers={'X-API-Key': os.environ['MUNGFALI_API_KEY']},
    timeout=30,
)
response.raise_for_status()
data = response.json()

for image in data['value']:
    print(image['imageUrl'])

PHP

Use cURL or Guzzle; keep the API key in server-side environment variables only.

php
<?php
$ch = curl_init('https://mungfali.net/v1/search?q=car&count=10');
curl_setopt_array($ch, [
    CURLOPT_HTTPHEADER => ['X-API-Key: ' . getenv('MUNGFALI_API_KEY')],
    CURLOPT_RETURNTRANSFER => true,
]);
$body = curl_exec($ch);
$data = json_decode($body, true);
echo $data['value'][0]['imageUrl'];

UI integration patterns

Image grid

Request count=24 or higher for masonry or grid layouts. Use width, height, and accentColor for placeholders and skeleton screens.

javascript
const { value: images } = await searchImages('interior design', { count: 24 });

images.forEach((img) => {
  const el = document.createElement('img');
  el.src = img.imageUrl;
  el.width = img.width;
  el.height = img.height;
  el.alt = img.name;
  grid.appendChild(el);
});

Attribution and linking

Each result includes hostUrl — the page where the image was found. Link to hostUrl when your product policy requires attribution to the source site.

Caching

Cache search results server-side keyed by q plus filter parameters. Respect your plan quota; avoid polling the same query in a tight loop. A TTL of 5–60 minutes is typical for non-real-time UIs.

Handling errors

javascript
const res = await fetch(url, { headers: { 'X-API-Key': key } });
const body = await res.json();

switch (res.status) {
  case 200:
    return body.value;
  case 401:
    throw new Error('Check API key');
  case 402:
    throw new Error('Upgrade subscription');
  case 429:
    throw new Error(body.error); // quota or rate limit
  default:
    throw new Error(body.error || 'Search failed');
}

Next steps