Cropspy Disease Scouting Guide API - Documentation

The Cropspy Disease Scouting Guide API provides weather-based disease Scouting Guide for various crops based on location.

The Pest Triangle: Understanding Disease Development in Crops

Plant diseases do not occur randomly; they require three essential components to align simultaneously. This concept is known as the Pest Triangle, which consists of:

1. Host (Crop Susceptibility)

A plant species must be susceptible to a particular disease. Different crops have varying levels of resistance or susceptibility to specific pathogens. For example, grapevines are susceptible to downy mildew, whereas wheat is not.

2. Inoculum (Pathogen Presence)

The presence of the disease-causing organism (fungus, bacteria, virus, or nematode) is crucial. Inoculum sources include infected plant debris, contaminated soil, seeds, and insect vectors. For example, Fusarium wilt in bananas persists in soil for years, even without a host plant.

3. Favorable Climate (Environmental Conditions)

Even if a susceptible crop and inoculum are present, the disease can only develop if the climatic conditions support pathogen growth. This includes temperature, humidity, rainfall, and leaf wetness duration. For example, late blight of potato thrives in cool, wet conditions, whereas powdery mildew favors warm, dry environments.

Why Do All Three Factors Need to Align?

A disease outbreak only occurs when all three elements of the pest triangle intersect at the right time and place. If any one factor is missing, the disease cannot establish or spread. For example:

This understanding allows farmers to take proactive disease management decisions, targeting one or more sides of the triangle to break the disease cycle.


The Role of Climate in Disease Risk Estimation

In many cases, the host (crop) is already known, and the presence of inoculum is uncertain—especially at the field level. However, climate parameters can serve as a strong predictive tool in such situations.

It is important to note that our system does not directly predict disease occurrence. Instead, it assesses climatic suitability for known crop diseases, helping farmers make informed decisions.


Understanding Disease Risk Levels in Our System

Based on the analysis of climate parameters, disease risk levels are categorized as follows:

1. Very Likely (🔴 Highest Risk)

2. More Likely (🟠 Moderate to High Risk)

3. Likely (🟡 Moderate Risk)

4. Observe (🔵 Low to Moderate Risk)

5. Cautious / Not Likely (⚪ Minimal Risk)


Conclusion

Our system does not predict disease outbreaks directly but instead evaluates climate suitability for disease development. Since we already know the host (crop) but not always the inoculum (pathogen presence), analyzing climate factors allows for risk-based decision-making.

By understanding disease risk levels based on climate conditions, farmers can:

This approach empowers farmers with scientific insights while avoiding over-promising or misleading predictions. Farmers remain in control of their decisions based on factual climate risk assessments.

Base URL

https://cropspy.in/disapi.php

Request Method

GET

Query Parameters

Parameter Type Required Description
pincode String Yes 6-digit Indian postal code to fetch location-specific data.
id String Yes The name of the crop (e.g., Tomato, Cotton, Maize).
key String Yes Your API key for authentication.

Example Request

https://cropspy.in/disapi.php?pincode=425001&id=Tomato&key=YOUR_API_KEY

Response Format

The API returns disease prediction alerts based on temperature and humidity conditions.

{
    "Disease Name": {
        "Very Likely": ["10-Mar", "12-Mar"],
        "More Likely": ["14-Mar", "15-Mar"]
    }
}

Use Cases

Integration in Various Languages

Python

import requests
response = requests.get("https://cropspy.in/disapi.php?pincode=425001&id=Tomato&key=YOUR_API_KEY")
print(response.json())

PHP


// Your API Key (Replace with your actual API key)
$key = "YOUR_API_KEY";
// Get dynamic parameters
$pincode = $_GET['pincode'] ?? "425001";
$crop_id = $_GET['id'] ?? "Tomato";
// API endpoint
$api_url = "https://cropspy.in/disapi.php?pincode={$pincode}&id={$crop_id}&key={$key}";
// Fetch API response
$json_data = file_get_contents($api_url);
$response_data = json_decode($json_data, true);
// Check for errors in response
if (!$response_data || isset($response_data['error'])) {
    die("<b> Error:</b> " . ($response_data['error'] ?? "Invalid API response"));
}
// Display results
echo "Disease Predictions for $crop_id (Pincode: $pincode)";
foreach ($response_data as $disease => $levels) {
    echo "<strong>$disease</strong><br>";
    foreach ($levels as $severity => $dates) {
        echo "<span style='color: red;'>$severity:</span>" . implode(", ", $dates) . "<br>";
    }
    echo "<br>";
    

Twilio WhatsApp API (PHP)


require __DIR__ . '/vendor/autoload.php';
use Twilio\Rest\Client;

$sid = "YOUR_TWILIO_SID";
$token = "YOUR_TWILIO_AUTH_TOKEN";
$twilio = new Client($sid, $token);

$to = "whatsapp:+919876543210"; // Replace with farmer's number
$from = "whatsapp:+14155238886"; // Twilio's WhatsApp number
$message = "Disease alert for Tomato in 425001:\n- Very Likely: 10-Mar, 12-Mar";

$twilio->messages->create($to, ["from" => $from, "body" => $message]);

echo "Message Sent!";

Kotlin (Android - OkHttp)


import okhttp3.*
import org.json.JSONObject

fun fetchDiseaseData(pincode: String, cropId: String, apiKey: String) {
    val url = "https://cropspy.in/disapi.php?pincode=$pincode&id=$cropId&key=$apiKey"
    val client = OkHttpClient()
    val request = Request.Builder().url(url).build()

    client.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            println("API Request Failed: ${e.message}")
        }

        override fun onResponse(call: Call, response: Response) {
            val jsonData = response.body?.string()
            val jsonObject = JSONObject(jsonData ?: "{}")

            if (jsonObject.has("error")) {
                println("Error: ${jsonObject.getString("error")}")
            } else {
                println("Disease Predictions:")
                jsonObject.keys().forEach { disease ->
                    println("\n$disease:")
                    val severityObj = jsonObject.getJSONObject(disease)
                    severityObj.keys().forEach { severity ->
                        println("$severity: ${severityObj.getJSONArray(severity).join(", ")}")
                    }
                }
            }
        }
    })
}

How to Store API Key in Android

1. Hardcoded in the Code (Not Recommended)


val apiKey = "YOUR_API_KEY"
fetchDiseaseData("425001", "Tomato", apiKey)

⚠️ Risk: Hardcoding API keys is a security risk, as they can be extracted from decompiled APK files.


2. Store in gradle.properties (Safer)

Step 1: Open gradle.properties (in the gradle folder) and add:


API_KEY="YOUR_API_KEY"

Step 2: Access it in Kotlin code:


val apiKey = BuildConfig.API_KEY
fetchDiseaseData("425001", "Tomato", apiKey)

Step 3: In app/build.gradle, add:


android {
    defaultConfig {
        buildConfigField "String", "API_KEY", "\"${API_KEY}\""
    }
}

3. Store in local.properties (For Development Only)

Step 1: Add to local.properties (in project root):


api.key=YOUR_API_KEY

Step 2: Read in gradle.properties:


API_KEY = project.findProperty("api.key") ?: ""

Step 3: Use it in code:


val apiKey = BuildConfig.API_KEY
fetchDiseaseData("425001", "Tomato", apiKey)

4. Store in res/values/strings.xml (Better than Hardcoding)

Step 1: Add in res/values/strings.xml:


YOUR_API_KEY

Step 2: Use in Kotlin:


val apiKey = context.getString(R.string.api_key)
fetchDiseaseData("425001", "Tomato", apiKey)

5. Use Secure Storage (Most Secure)

Use Android Keystore or EncryptedSharedPreferences to store the API key securely.


✅ Best Practice

If your API key is sensitive, avoid hardcoding it and use gradle.properties or Keystore.

JavaScript (Node.js - Fetch API)


const fetch = require('node-fetch');

const pincode = "425001";
const crop_id = "YOUR_API_KEY";
const api_url = `https://cropspy.in/disapi.php?pincode=${pincode}&id=${crop_id}&key=${api_key}`;

fetch(api_url)
    .then(response => response.json())
    .then(data => {
        if (data.error) {
            console.error("Error:", data.error);
        } else {
            console.log(`Disease Predictions for ${crop_id} (Pincode: ${pincode})`);
            Object.entries(data).forEach(([disease, levels]) => {
                console.log(`\n${disease}:`);
                Object.entries(levels).forEach(([severity, dates]) => {
                    console.log(`${severity}: ${dates.join(", ")}`);
                });
            });
        }
    })
    .catch(error => console.error("API Request Failed:", error));

Python (Requests)


import requests

pincode = "425001"
crop_id = "Tomato"
api_key = "YOUR-API-KEY"
api_url = f"https://cropspy.in/disapi.php?pincode={pincode}&id={crop_id}&key={api_key}"

response = requests.get(api_url)
data = response.json()

if "error" in data:
    print("Error:", data["error"])
else:
    print(f"Disease Predictions for {crop_id} (Pincode: {pincode})")
    for disease, levels in data.items():
        print(f"\n{disease}:")
        for severity, dates in levels.items():
            print(f"{severity}: {', '.join(dates)}")

Supported Crops and Pincode Format

✅ Pincode Format

Only 6-digit Indian pincodes are supported. Example: 425001, 110001, 560001.

Coverage: We currently serve approximately 195,000 pincodes across India.


🌱 Supported Crops


🔹 How to Use Crop Names in API Calls

Important: Use the exact crop names as listed above when making API requests.


https://cropspy.in/disapi.php?pincode=425001&id=Tomato&key=YOUR_API_KEY

✔️ Example: To fetch disease data for Tomato in pincode 425001, use id=Tomato.

Support

For queries, contact support@cropspy.in