Media Search API

Media Search API: Find crop reference images by natural language

The Media Search API lets you retrieve annotated crop disease reference images using a plain-language query. It combines full-text and vector search to match farmer descriptions to the most relevant visual examples — supporting both direct search and a guided multi-turn diagnostic flow.

POST /api/v1/media/{plant}/search Scope: media:search

Authentication

All Media Search API endpoints require a valid API key passed in the Authorization header:

Authorization: Bearer YOUR_API_KEY

Your API key must have the media API enabled and carry the media:search scope. Keys are issued per application from the FildraAI developer dashboard. Requests without a valid key return 401 Unauthorized.

Usage billing

POST search and diagnose requests are billed per call. GET search requests are read-only and not billed. Billing is tracked against the API key used in the request.

Endpoints

GET /api/v1/media/{plant}/search

Read-only search. Pass q, locale, and optional filters as query parameters. Not billed. Use for lightweight lookups or cached requests.

POST /api/v1/media/{plant}/search

Billed search with JSON body. Supports all parameters including category and image_group filters. Preferred for production use.

POST /api/v1/media/{plant}/diagnose

Multi-turn diagnostic flow. The API asks clarifying questions when ambiguity is high, then returns matched images once confidence exceeds the threshold. Maintains state via an echo session object.

POST /api/v1/media/search (legacy)

Backward-compatible endpoint accepting plant in the request body rather than the URL path. Supported for existing integrations; new integrations should use the plant-path form.

Search request parameters

For POST /api/v1/media/{plant}/search, send a JSON body with the following fields:

Required

  • q (string) — Natural-language description of the crop symptom or search query
  • locale (string) — Locale key for the response language, e.g. en-us, sw-ke, fr-af

Optional

  • k (integer, default 8) — Maximum number of images to return
  • scope (string, default "global") — Geographic scope filter
  • category (string) — Filter by image category tag
  • image_group (string) — Filter by image group identifier
  • include_scores (boolean, default false) — Include relevance scores in each result item

Example request

POST /api/v1/media/maize/search
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
  "q": "yellowing leaves with brown spots near the base",
  "locale": "en-us",
  "k": 5
}

Response schema

A successful response returns 200 OK with the following JSON structure:

{
  "ok": true,
  "count": 5,
  "items": [
    {
      "id": "img_abc123",
      "title": "Gray Leaf Spot — maize — early stage",
      "file": "gls_maize_early_001.jpg",
      "plant": "maize",
      "class": "gray_leaf_spot",
      "topic": "disease",
      "locale": "en-us",
      "score": 0.91,
      "media_download_url": "https://...",
      "tags": ["leaf", "fungal", "early-stage"],
      "category": "field",
      "image_group": "gls_set_a"
    }
  ],
  "meta": {
    "query": "yellowing leaves with brown spots",
    "plant": "maize",
    "locale": "en-us",
    "took_ms": 124
  }
}

Each item in items represents a matched reference image. The score field is only present if include_scores was set to true in the request. Internal storage URLs are stripped from the response for security — use media_download_url to access the image.

Staged diagnostic flow

The /diagnose endpoint runs a multi-turn disambiguation flow. Rather than immediately returning images, it may first ask one or more clarifying questions to narrow the search. This is useful when a description could match multiple disease classes.

Turn 1 — Initial query

  • Send q and locale; omit session
  • If action is ask_question, show the question from question.ask to the user
  • Store the full session object from the response

Turn 2+ — Answer and continue

  • Echo the session object from the previous response
  • Add the farmer's answer inside session.answers[question_id]
  • When action becomes show_images, the items array contains the matched images

Confidence threshold

The diagnostic flow moves to show_images once confidence exceeds 0.75 or after three disambiguation rounds, whichever comes first. The ambiguity field in each response (one of very_high, high, medium, low) reflects current uncertainty.

Locale and language support

The locale parameter controls both the language of metadata returned and the search index used. If the requested locale is not available for the given crop, the API falls back to the closest available locale (usually en-us) and sets fallback_used: true in the response.

Supported locales

  • en-us — English
  • sw-ke — Kiswahili (East Africa)
  • fr-af — French (West/Central Africa)
  • zh-cn — Simplified Chinese
  • zh-tw — Traditional Chinese

Fallback behaviour

  • Each response item includes requested_locale and served_locale fields
  • fallback_used: true means the index was served from a different locale than requested
  • If no locale index exists at all, the API returns 404 with error media_not_found

Error codes

The Media Search API returns standard HTTP status codes. Common error cases:

Client errors (4xx)

  • 400 — Missing or invalid parameter (e.g. empty q or missing locale)
  • 401 — Missing or invalid API key
  • 403 — Key does not have the required scope or audience
  • 404 — Media index not found for the requested plant and locale
  • 429 — Rate limit exceeded

Server errors (5xx)

  • 500 — Internal error (media_search_failed or media_diagnose_failed)
  • 503 — Media index is being rebuilt (media_build_pending); retry after a short delay

503 during index rebuild

When a crop index is being rebuilt in the background, search requests return 503 with error code media_build_pending. This is a temporary state — the response message will indicate when the build is expected to complete. Implement exponential backoff before retrying.