Diagnosis API · Technical Documentation

Image diagnosis, AI focus areas, and supporting knowledge for authenticated developer workflows

The public diagnosis gateway accepts multipart image uploads, authenticates the caller, stages the image in storage on the user's behalf, and runs crop diagnosis. Results are designed to support explainable image diagnosis workflows and can be paired with diagnosis knowledge in your broader integration.

multipart/form-data upload
user API key required
4 crops supported
JSON response with gateway metadata

API Reference

Public upload endpoint

This page documents the public upload flow used by developers and product teams. For internal server-side S3-staged workflows, separate raw-key diagnosis endpoints exist and are authenticated differently.

POST /api/v1/diagnose

Upload a crop image using multipart/form-data. The API validates the request, uploads the image to managed storage on the caller's behalf, then runs image diagnosis. This avoids exposing internal storage credentials to end users.

Authentication
X-Api-Key: <your_key>
Alternative: Authorization: Bearer <your_key>
Audience
Public upload gateway for user-scoped API keys. Internal raw-key diagnosis endpoints are separate and server-scoped.
Request Method
POST with multipart/form-data
File Upload
Form field: image (binary file data)
Query Parameters
plant (required), top_k (optional), locale (optional)
Supported Plants
cassava, maize, rice, tomato
Locale Resolution
Priority: ?locale=...Accept-Languageen-us
Query parameter takes priority if both are set

Query Parameters

Parameter Type Required Description
plant String Yes Plant type to diagnose. Must be one of: cassava, maize, rice, tomato.
top_k Integer No Number of predictions to return. Accepted range is 1–10. If omitted, the service uses 3.
locale String No Preferred response locale. Common examples include en-us and zh-tw. Unsupported values are rejected by the diagnosis service.
Implementation note: this public endpoint is the upload gateway. It is different from internal raw-key inference routes used by server-side pipelines that already stage images in storage.

Additional Diagnosis Paths

Server workflows already referenced on this site

These endpoints are for staged-image server flows and knowledge-backed diagnosis. They are already referenced in our solutions overview, so the examples below document the exact JSON contracts developers need.

POST /api/v1/image_diagnosis/infer/basic

Use this when your backend already has a staged object key. The request body is JSON, the key audience can be user or server, and the response returns raw diagnosis output with Grad-CAM URLs but without knowledge enrichment.

Field Type Required Description
plantStringYescassava, maize, rice, or tomato.
raw_keyStringYesPreviously staged storage key, for example uploads/diagnose/user-123/maize/sample.jpg.
localeStringNoResponse locale. Falls back to request locale handling when omitted.
job_idStringNoOptional caller-supplied correlation id. Generated server-side if omitted.
top_kIntegerNoPrediction count. Defaults to 3, capped at 10.
countryStringNoReserved for future geographic filtering and logging.
POST /api/v1/image_diagnosis/infer/with_knowledge

This is the knowledge-backed variant of raw-key diagnosis. It returns the same prediction core plus a knowledge object per prediction, with section filtering and resolved citations already embedded where applicable.

Field Type Required Description
plantStringYesCrop scope for inference and profile resolution.
raw_keyStringYesStaged object key for the image already stored by your backend flow.
sectionsArray<string> or CSV stringNoProfile sections to keep. Examples: ["visual_profile","lookalikes"] or "visual_profile,decision_support".
lookalikesBooleanNoAlias flag that expands to the matching section set.
visual_profileBooleanNoAlias flag for visual explanation sections.
decision_supportBooleanNoAlias flag for management guidance sections.
Allowed sections: cause, linkage, model_integration, visual_profile, lookalikes, decision_support, progression_profile, geographic_applicability, assistant_contract, evidence, evidence_summary, data_quality, validation_warnings.

Usage & Limits

Quotas currently enforced

These limits reflect the current implementation. Playground quotas and API key quotas are tracked differently, so you should design clients to handle quota exhaustion cleanly.

Guest playground
3 uses
Guest playground traffic is limited to 3 uses per 8-hour quota window. This is tracked in the visitor's Flask session.
Authenticated playground
9 uses
Authenticated playground usage is limited to 9 uses per 8-hour quota window. This is tracked on the user record.
API key quota
10 free calls / month
Paid API credits are available as a one-time top-up after the free monthly API allowance is exhausted.

How usage is calculated

  • Guest and authenticated playground windows are separate from API key usage.
  • Playground quota windows currently use an 8-hour rolling window marker.
  • Free API key usage is counted against the current calendar month; paid API credits do not reset monthly.
  • Clients should handle authentication, quota, and validation failures explicitly rather than assuming every non-200 response is transient.
Phase 1 paid access: the Diagnosis Test Pack is a one-time purchase: About US$1.00 · charged as NT$30 via LINE Pay · 10 API credits. It is not a subscription or permanent tier upgrade.

Code Examples

Integration Examples

Use the public upload gateway when your client has the image file locally and should not handle internal storage credentials directly.

cURL — Basic Request
# Diagnose a maize image through the public upload gateway
curl -X POST "https://api.yourdomain.com/api/v1/diagnose?plant=maize&top_k=3&locale=en-us" \
  -H "X-Api-Key: YOUR_USER_API_KEY" \
  -F "image=@maize_leaf.jpg"
Python — Raw-Key Basic Inference
# Server-side inference when the image is already staged in storage
import requests

base_url = "https://api.yourdomain.com"
api_key = "YOUR_SERVER_OR_USER_API_KEY"

url = f"{base_url}/api/v1/image_diagnosis/infer/basic"
payload = {
    "plant": "rice",
    "raw_key": "uploads/diagnose/team-42/rice/rice_leaf.jpg",
    "locale": "en-us",
    "job_id": "demo-job-001",
    "top_k": 3,
    "country": "zambia"
}
headers = {
    "X-Api-Key": api_key,
    "Content-Type": "application/json"
}

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

result = response.json()
print(result)
JavaScript — Knowledge-Enriched Diagnosis
// Server-side diagnosis + filtered knowledge sections
async function diagnoseWithKnowledge(rawKey) {
  const response = await fetch("https://api.yourdomain.com/api/v1/image_diagnosis/infer/with_knowledge", {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Api-Key': 'YOUR_SERVER_OR_USER_API_KEY'
    },
    body: JSON.stringify({
      plant: 'tomato',
      raw_key: rawKey,
      locale: 'en-us',
      top_k: 2,
      sections: ['visual_profile', 'lookalikes', 'decision_support'],
      lookalikes: true
    })
  });

  return await response.json();
}

Response Examples

Successful response

The exact diagnosis payload may evolve, but the gateway metadata block is intended to help trace uploaded requests and diagnosis jobs.

Example Success Response
{
  "success": true,
  "plant": "maize",
  "locale": "en-us",
  "kb_locale": "en-us",
  "job_id": "2ae7df30-3e3b-4d7b-b89d-6626a3d08b02",
  "top_k": 3,
  "raw_key": "uploads/diagnose/user-123/maize/leaf_sample.jpg",
  "result_key": "diagnostics/gradcams/2ae7df30-3e3b-4d7b-b89d-6626a3d08b02/result.json",
  "result_url": "https://signed-storage-url.example/result.json",
  "predictions": [
    {
      "class_index": 4,
      "label": "grey_leaf_spot",
      "confidence": 0.9412,
      "gradcam_key": "diagnostics/gradcams/.../pred_1.png",
      "gradcam_url": "https://signed-storage-url.example/pred_1.png"
    },
    {
      "class_index": 2,
      "label": "common_rust",
      "confidence": 0.0418,
      "gradcam_key": "diagnostics/gradcams/.../pred_2.png",
      "gradcam_url": "https://signed-storage-url.example/pred_2.png"
    }
  ],
  "gateway": {
    "request_id": "8db75450-0a61-47d4-841d-3e7899787598",
    "job_id": "2ae7df30-3e3b-4d7b-b89d-6626a3d08b02",
    "timestamp": "2026-05-04T09:12:54Z",
    "uploaded_s3_key": "uploads/diagnose/user-123/maize/leaf_sample.jpg",
    "plant": "maize",
    "locale": "en-us",
    "top_k": 3,
    "user_id": "user-123"
  },
  "supported_plants": ["cassava", "maize", "rice", "tomato"]
}

Error response

Validation, authentication, quota, and server failures should all be handled explicitly in client code.

Example Error Response
{
  "success": false,
  "error": "bad_request",
  "message": "Unsupported plant: 'wheat'. Supported plants: cassava, maize, rice, tomato",
  "status_code": 400
}
Implementation note: do not hard-code an exact prediction schema unless your deployment contract guarantees it. Safely parse the gateway metadata and handle validation or quota failures separately from model output.
Knowledge-backed variant: the response from /api/v1/image_diagnosis/infer/with_knowledge keeps the same top-level fields and adds canonical_disease_key plus a per-prediction knowledge object containing the filtered profile sections you requested.

Common error classes

  • 400 Bad Request: missing query parameter, unsupported plant, invalid image type, empty file, or file too large
  • 401 Unauthorized: missing API key or invalid API key
  • 403 Forbidden: wrong audience, missing scope, or API not allowed for the key
  • Quota exceeded: usage rejected after the configured guest, authenticated, or API-key quota is exhausted
  • 500 Internal Server Error: storage or diagnosis engine failure

Need more diagnosis API calls?

Buy a one-time Diagnosis Test Pack from your account billing page. Credits are granted only after FildraPay confirms canonical payment success.