# Recipe: Historical Lightning

import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "zudoku/ui/Accordion";

export const StepHeader = ({ n, children }) => (
  <span style={{ display: "inline-flex", alignItems: "center", gap: "0.75rem" }}>
    <span style={{
      display: "inline-flex",
      alignItems: "center",
      justifyContent: "center",
      width: "1.75rem",
      height: "1.75rem",
      minWidth: "1.75rem",
      borderRadius: "9999px",
      backgroundColor: "#F05514",
      color: "#FFFFFF",
      fontSize: "0.875rem",
      fontWeight: 600,
      flexShrink: 0,
      lineHeight: 1,
    }}>
      {n}
    </span>
    <span>{children}</span>
  </span>
);

This recipe shows how to query historical lightning data to find out whether strikes occurred near a location on a given date.

:::note
**These recipes are teaching examples — not production code.**

- **Host:** examples use the development host **apidev.accuweather.com**. Switch to **api.accuweather.com** for production.
- **Production hardening:** GZIP compression, caching, retries with exponential backoff, and error handling are not included. See the [Best Practices](/developers/best-practices) guide.
:::

## Scenario

> "There was a big storm last week. I want to see how many lightning strikes happened near my area that day."

---

<Accordion type="multiple" defaultValue={["step-1"]} className="my-6">

<AccordionItem value="step-1">
  <AccordionTrigger><StepHeader n={1}>Make the request</StepHeader></AccordionTrigger>
  <AccordionContent>

Call the Historical lightning endpoint with a location's coordinates, a search radius, and the date you're interested in.

**Endpoint:**
```
GET https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey={YOUR_API_KEY}&q={latitude},{longitude}&distanceRadius={miles}&startDate={mm/dd/yyyy}
```

<CodeTabs syncKey="language">

```ts title="TypeScript"
const apiKey = "{YOUR_API_KEY}";
const lat = 28.37;
const lon = -81.57;
const radius = 20;
const date = "10/27/2025";

const res = await fetch(
  `https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey=${apiKey}&q=${lat},${lon}&distanceRadius=${radius}&startDate=${encodeURIComponent(date)}`
);
const data: Record<string, any> = await res.json();
console.log(`Total strikes: ${data.resultsCount}`);
```

```python title="Python"
import requests

API_KEY = "{YOUR_API_KEY}"
lat, lon = 28.37, -81.57
radius = 20
date = "10/27/2025"

resp = requests.get(
    "https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius",
    params={
        "apikey": API_KEY,
        "q": f"{lat},{lon}",
        "distanceRadius": radius,
        "startDate": date,
    },
)
data = resp.json()
print(f"Total strikes: {data['resultsCount']}")
```

```csharp title="C#"
using var client = new HttpClient();

var apiKey = "{YOUR_API_KEY}";
var lat = 28.37;
var lon = -81.57;
var radius = 20;
var date = "10/27/2025";

var response = await client.GetStringAsync(
    $"https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey={apiKey}&q={lat},{lon}&distanceRadius={radius}&startDate={Uri.EscapeDataString(date)}");
```

```java title="Java"
HttpClient client = HttpClient.newHttpClient();
String apiKey = "{YOUR_API_KEY}";
double lat = 28.37, lon = -81.57;
int radius = 20;
String date = "10/27/2025";

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(
        "https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey="
        + apiKey + "&q=" + lat + "," + lon + "&distanceRadius=" + radius
        + "&startDate=" + URLEncoder.encode(date, StandardCharsets.UTF_8)))
    .build();

HttpResponse<String> response =
    client.send(request, HttpResponse.BodyHandlers.ofString());
```

```bash title="bash"
curl "https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey={YOUR_API_KEY}&q=28.37,-81.57&distanceRadius=20&startDate=10/27/2025"
```

</CodeTabs>

:::tip
Add `&strikeType=cg` to filter results to cloud-to-ground strikes only — the type most relevant for ground-level impact.
:::

  </AccordionContent>
</AccordionItem>

<AccordionItem value="step-2">
  <AccordionTrigger><StepHeader n={2}>Inspect the response</StepHeader></AccordionTrigger>
  <AccordionContent>

The response includes a summary with strike counts and the closest strike, plus the full list of individual strikes.

```json
{
  "pageCount": -1,
  "resultsCount": 4933,
  "lightningSummary": {
    "positiveStrikes": 487,
    "negativeStrikes": 732,
    "closestStrike": {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "geometry": {
            "type": "Point",
            "coordinates": [-81.57269, 28.36983]
          },
          "properties": {
            "id": "66d48bf7-76f4-523e-a0a4-6b8fbd325ca2",
            "date": "2025-10-27T21:39:20+00:00",
            "sourceId": 84,
            "strikeType": "",
            "peakCurrent": null
          }
        }
      ]
    }
  },
  "lightningStrikes": {
    "type": "FeatureCollection",
    "features": [
      {
        "type": "Feature",
        "geometry": {
          "type": "Point",
          "coordinates": [-81.67091, 28.59686]
        },
        "properties": {
          "id": "7390fc2a-122c-5f66-a9f6-655bc7f0979a",
          "date": "2025-10-27T02:01:47+00:00",
          "sourceId": 86,
          "strikeType": "cg",
          "peakCurrent": -3780000
        }
      }
    ]
  }
}
```

  </AccordionContent>
</AccordionItem>

<AccordionItem value="step-3">
  <AccordionTrigger><StepHeader n={3}>Summarize the activity</StepHeader></AccordionTrigger>
  <AccordionContent>

<CodeTabs syncKey="language">

```ts title="TypeScript"
const summary = data.lightningSummary;
const totalCG = summary.positiveStrikes + summary.negativeStrikes;
const closest = summary.closestStrike.features[0];
const [closestLon, closestLat] = closest.geometry.coordinates;

console.log("⚡ Lightning Summary");
console.log("━".repeat(36));
console.log(`Date:              ${date}`);
console.log(`Search area:       ${radius} miles from ${lat}, ${lon}`);
console.log(`Total strikes:     ${data.resultsCount}`);
console.log(`Cloud-to-ground:   ${totalCG} (${summary.positiveStrikes} positive, ${summary.negativeStrikes} negative)`);
console.log(`Closest strike:    ${closestLat.toFixed(4)}, ${closestLon.toFixed(4)}`);
console.log(`Closest time:      ${closest.properties.date}`);

if (data.resultsCount === 0) {
  console.log("\nNo lightning detected in this area on this date.");
} else if (totalCG > 100) {
  console.log("\nSignificant lightning activity detected.");
} else {
  console.log("\nSome lightning activity detected.");
}
```

```python title="Python"
summary = data["lightningSummary"]
total_cg = summary["positiveStrikes"] + summary["negativeStrikes"]
closest = summary["closestStrike"]["features"][0]
closest_lon, closest_lat = closest["geometry"]["coordinates"]

print("⚡ Lightning Summary")
print("━" * 36)
print(f"Date:              {date}")
print(f"Search area:       {radius} miles from {lat}, {lon}")
print(f"Total strikes:     {data['resultsCount']}")
print(f"Cloud-to-ground:   {total_cg} ({summary['positiveStrikes']} positive, {summary['negativeStrikes']} negative)")
print(f"Closest strike:    {closest_lat:.4f}, {closest_lon:.4f}")
print(f"Closest time:      {closest['properties']['date']}")

if data["resultsCount"] == 0:
    print("\nNo lightning detected in this area on this date.")
elif total_cg > 100:
    print("\nSignificant lightning activity detected.")
else:
    print("\nSome lightning activity detected.")
```

```csharp title="C#"
using System.Text.Json;

var doc = JsonDocument.Parse(response);
var summary = doc.RootElement.GetProperty("lightningSummary");
var positive = summary.GetProperty("positiveStrikes").GetInt32();
var negative = summary.GetProperty("negativeStrikes").GetInt32();
var totalCG = positive + negative;
var resultsCount = doc.RootElement.GetProperty("resultsCount").GetInt32();
var closest = summary.GetProperty("closestStrike").GetProperty("features")[0];
var closestLon = closest.GetProperty("geometry").GetProperty("coordinates")[0].GetDouble();
var closestLat = closest.GetProperty("geometry").GetProperty("coordinates")[1].GetDouble();
var closestDate = closest.GetProperty("properties").GetProperty("date").GetString();

Console.WriteLine("⚡ Lightning Summary");
Console.WriteLine(new string('━', 36));
Console.WriteLine($"Date:              {date}");
Console.WriteLine($"Search area:       {radius} miles from {lat}, {lon}");
Console.WriteLine($"Total strikes:     {resultsCount}");
Console.WriteLine($"Cloud-to-ground:   {totalCG} ({positive} positive, {negative} negative)");
Console.WriteLine($"Closest strike:    {closestLat:F4}, {closestLon:F4}");
Console.WriteLine($"Closest time:      {closestDate}");

Console.WriteLine(resultsCount == 0
    ? "\nNo lightning detected in this area on this date."
    : totalCG > 100
        ? "\nSignificant lightning activity detected."
        : "\nSome lightning activity detected.");
```

```java title="Java"
import org.json.JSONObject;

var doc = new JSONObject(response.body());
var summary = doc.getJSONObject("lightningSummary");
var positive = summary.getInt("positiveStrikes");
var negative = summary.getInt("negativeStrikes");
var totalCG = positive + negative;
var resultsCount = doc.getInt("resultsCount");
var closest = summary.getJSONObject("closestStrike")
    .getJSONArray("features").getJSONObject(0);
var coords = closest.getJSONObject("geometry").getJSONArray("coordinates");
var closestDate = closest.getJSONObject("properties").getString("date");

System.out.println("⚡ Lightning Summary");
System.out.println("━".repeat(36));
System.out.printf("Date:              %s%n", date);
System.out.printf("Search area:       %d miles from %.2f, %.2f%n", radius, lat, lon);
System.out.printf("Total strikes:     %d%n", resultsCount);
System.out.printf("Cloud-to-ground:   %d (%d positive, %d negative)%n", totalCG, positive, negative);
System.out.printf("Closest strike:    %.4f, %.4f%n", coords.getDouble(1), coords.getDouble(0));
System.out.printf("Closest time:      %s%n", closestDate);

System.out.println(resultsCount == 0
    ? "\nNo lightning detected in this area on this date."
    : totalCG > 100
        ? "\nSignificant lightning activity detected."
        : "\nSome lightning activity detected.");
```

```bash title="bash"
curl -s "https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey={YOUR_API_KEY}&q=28.37,-81.57&distanceRadius=20&startDate=10/27/2025" \
  | jq '{
    total: .resultsCount,
    positive_cg: .lightningSummary.positiveStrikes,
    negative_cg: .lightningSummary.negativeStrikes,
    closest_time: .lightningSummary.closestStrike.features[0].properties.date
  }'
```

</CodeTabs>

  </AccordionContent>
</AccordionItem>

<AccordionItem value="step-4">
  <AccordionTrigger><StepHeader n={4}>Find the strongest strikes</StepHeader></AccordionTrigger>
  <AccordionContent>

Positive cloud-to-ground strikes carry more charge and last longer. Sort by `peakCurrent` to find the most powerful ones:

<CodeTabs syncKey="language">

```ts title="TypeScript"
const strikes = data.lightningStrikes.features
  .filter((f: any) => f.properties.peakCurrent !== null)
  .sort((a: any, b: any) => Math.abs(b.properties.peakCurrent) - Math.abs(a.properties.peakCurrent))
  .slice(0, 5);

console.log("\nTop 5 strongest strikes:");
for (const s of strikes) {
  const [sLon, sLat] = s.geometry.coordinates;
  const current = s.properties.peakCurrent;
  const polarity = current > 0 ? "+" : "−";
  console.log(`  ${sLat.toFixed(4)}, ${sLon.toFixed(4)}  ${polarity}${Math.abs(current)}A  ${s.properties.date}`);
}
```

```python title="Python"
strikes = [
    f for f in data["lightningStrikes"]["features"]
    if f["properties"]["peakCurrent"] is not None
]
strikes.sort(key=lambda f: abs(f["properties"]["peakCurrent"]), reverse=True)

print("\nTop 5 strongest strikes:")
for s in strikes[:5]:
    slon, slat = s["geometry"]["coordinates"]
    current = s["properties"]["peakCurrent"]
    polarity = "+" if current > 0 else "−"
    print(f"  {slat:.4f}, {slon:.4f}  {polarity}{abs(current)}A  {s['properties']['date']}")
```

```csharp title="C#"
var topStrikes = doc.RootElement
    .GetProperty("lightningStrikes")
    .GetProperty("features")
    .EnumerateArray()
    .Where(f => f.GetProperty("properties").GetProperty("peakCurrent").ValueKind != JsonValueKind.Null)
    .OrderByDescending(f => Math.Abs(f.GetProperty("properties").GetProperty("peakCurrent").GetInt64()))
    .Take(5);

Console.WriteLine("\nTop 5 strongest strikes:");
foreach (var s in topStrikes)
{
    var c = s.GetProperty("geometry").GetProperty("coordinates");
    var sLon = c[0].GetDouble();
    var sLat = c[1].GetDouble();
    var current = s.GetProperty("properties").GetProperty("peakCurrent").GetInt64();
    var polarity = current > 0 ? "+" : "−";
    var sDate = s.GetProperty("properties").GetProperty("date").GetString();
    Console.WriteLine($"  {sLat:F4}, {sLon:F4}  {polarity}{Math.Abs(current)}A  {sDate}");
}
```

```java title="Java"
var allStrikes = doc.getJSONObject("lightningStrikes").getJSONArray("features");
var sorted = new java.util.ArrayList<JSONObject>();
for (int i = 0; i < allStrikes.length(); i++) {
    var obj = allStrikes.getJSONObject(i);
    if (!obj.getJSONObject("properties").isNull("peakCurrent")) {
        sorted.add(obj);
    }
}
sorted.sort((a, b) -> Long.compare(
    Math.abs(b.getJSONObject("properties").getLong("peakCurrent")),
    Math.abs(a.getJSONObject("properties").getLong("peakCurrent"))));

System.out.println("\nTop 5 strongest strikes:");
for (var s : sorted.subList(0, Math.min(5, sorted.size()))) {
    var c = s.getJSONObject("geometry").getJSONArray("coordinates");
    var current = s.getJSONObject("properties").getLong("peakCurrent");
    var polarity = current > 0 ? "+" : "−";
    System.out.printf("  %.4f, %.4f  %s%dA  %s%n",
        c.getDouble(1), c.getDouble(0),
        polarity, Math.abs(current),
        s.getJSONObject("properties").getString("date"));
}
```

```bash title="bash"
curl -s "https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey={YOUR_API_KEY}&q=28.37,-81.57&distanceRadius=20&startDate=10/27/2025" \
  | jq '[.lightningStrikes.features[]
    | select(.properties.peakCurrent != null)
    | {lat: .geometry.coordinates[1], lon: .geometry.coordinates[0],
       current: .properties.peakCurrent, date: .properties.date}]
    | sort_by(-.current | fabs) | .[:5]'
```

</CodeTabs>

  </AccordionContent>
</AccordionItem>

</Accordion>

---

## Pagination

Results come in pages of 5,000. Use the `offset` parameter as a **page index** (`0` = first set, `1` = second set, etc.) to fetch additional pages:

<CodeTabs syncKey="language">

```ts title="TypeScript"
let allStrikes: any[] = [];
let page = 0;

while (true) {
  const res = await fetch(
    `https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey=${apiKey}&q=${lat},${lon}&distanceRadius=${radius}&startDate=${encodeURIComponent(date)}&offset=${page}`
  );
  const pageData = await res.json();
  allStrikes.push(...pageData.lightningStrikes.features);
  if (pageData.lightningStrikes.features.length < 5000) break;
  page++;
}
```

```python title="Python"
all_strikes = []
page = 0
base_params = {
    "apikey": API_KEY,
    "q": f"{lat},{lon}",
    "distanceRadius": radius,
    "startDate": date,
}

while True:
    resp = requests.get(
        "https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius",
        params={**base_params, "offset": page},
    )
    page_data = resp.json()
    all_strikes.extend(page_data["lightningStrikes"]["features"])
    if len(page_data["lightningStrikes"]["features"]) < 5000:
        break
    page += 1
```

```csharp title="C#"
var allStrikesList = new List<JsonElement>();
int page = 0;

while (true)
{
    var pageResponse = await client.GetStringAsync(
        $"https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey={apiKey}&q={lat},{lon}&distanceRadius={radius}&startDate={Uri.EscapeDataString(date)}&offset={page}");
    var pageDoc = JsonDocument.Parse(pageResponse);
    var features = pageDoc.RootElement
        .GetProperty("lightningStrikes").GetProperty("features");
    foreach (var f in features.EnumerateArray()) allStrikesList.Add(f);
    if (features.GetArrayLength() < 5000) break;
    page++;
}
```

```java title="Java"
var allStrikesList = new java.util.ArrayList<JSONObject>();
int page = 0;

while (true) {
    var pageReq = HttpRequest.newBuilder()
        .uri(URI.create(
            "https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey="
            + apiKey + "&q=" + lat + "," + lon + "&distanceRadius=" + radius
            + "&startDate=" + URLEncoder.encode(date, StandardCharsets.UTF_8)
            + "&offset=" + page))
        .build();
    var pageResp = client.send(pageReq, HttpResponse.BodyHandlers.ofString());
    var features = new JSONObject(pageResp.body())
        .getJSONObject("lightningStrikes").getJSONArray("features");
    for (int i = 0; i < features.length(); i++) allStrikesList.add(features.getJSONObject(i));
    if (features.length() < 5000) break;
    page++;
}
```

```bash title="bash"
# First 5,000 results
curl "https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey={YOUR_API_KEY}&q=28.37,-81.57&distanceRadius=20&startDate=10/27/2025&offset=0"

# Next 5,000 results
curl "https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey={YOUR_API_KEY}&q=28.37,-81.57&distanceRadius=20&startDate=10/27/2025&offset=1"
```

</CodeTabs>

---

## Key response fields

| Field | Type | Description |
|-------|------|-------------|
| `resultsCount` | Integer | Total number of lightning strikes returned |
| `lightningSummary.positiveStrikes` | Integer | Count of positively-charged strikes |
| `lightningSummary.negativeStrikes` | Integer | Count of negatively-charged strikes |
| `lightningSummary.closestStrike` | Object | GeoJSON feature of the strike nearest to the search center |
| `lightningStrikes.features[]` | Array | GeoJSON features for each individual strike |
| `properties.strikeType` | String | `"cg"` (cloud-to-ground), `"ic"` (intra-cloud), or `""` (unknown) |
| `properties.peakCurrent` | Integer | Strike amperage. Positive = more energetic. Negative = most common. `null` if unavailable. |
| `properties.sourceId` | Integer | `84` (GOES East GLM), `85` (GOES West GLM), `86` (AccuWeather Lightning Network) |

---

## Understanding peak current

| Polarity | Description | Significance |
|----------|-------------|-------------|
| Positive (+) | Positively-charged cloud-to-ground strike | Typically more energetic. Carries more charge, longer duration. |
| Negative (-) | Negatively-charged cloud-to-ground strike | Most common type of lightning (~90% of CG strikes). |
| `null` | Not available | Data source does not provide amperage (GLM satellites). |

---

## Complete code sample

Copy a full, runnable example that queries historical lightning data and prints a summary.

<CodeTabs syncKey="language">

```ts title="TypeScript"
const API_KEY = "{YOUR_API_KEY}";
const lat = 28.37;
const lon = -81.57;
const radius = 20;
const date = "10/27/2025";

// Step 1: Fetch historical lightning data
const res = await fetch(
  `https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey=${API_KEY}&q=${lat},${lon}&distanceRadius=${radius}&startDate=${encodeURIComponent(date)}`
);
const data: Record<string, any> = await res.json();

// Step 2: Summarize the activity
const summary = data.lightningSummary;
const totalCG = summary.positiveStrikes + summary.negativeStrikes;
const closest = summary.closestStrike.features[0];
const [closestLon, closestLat] = closest.geometry.coordinates;

console.log("\n⚡ Lightning Summary");
console.log("━".repeat(36));
console.log(`Date:              ${date}`);
console.log(`Search area:       ${radius} miles from ${lat}, ${lon}`);
console.log(`Total strikes:     ${data.resultsCount}`);
console.log(`Cloud-to-ground:   ${totalCG} (${summary.positiveStrikes} positive, ${summary.negativeStrikes} negative)`);
console.log(`Closest strike:    ${closestLat.toFixed(4)}, ${closestLon.toFixed(4)}`);
console.log(`Closest time:      ${closest.properties.date}`);
```

```python title="Python"
import requests

API_KEY = "{YOUR_API_KEY}"
lat, lon = 28.37, -81.57
radius = 20
date = "10/27/2025"

# Step 1: Fetch historical lightning data
resp = requests.get(
    "https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius",
    params={
        "apikey": API_KEY,
        "q": f"{lat},{lon}",
        "distanceRadius": radius,
        "startDate": date,
    },
)
data = resp.json()

# Step 2: Summarize the activity
summary = data["lightningSummary"]
total_cg = summary["positiveStrikes"] + summary["negativeStrikes"]
closest = summary["closestStrike"]["features"][0]
closest_lon, closest_lat = closest["geometry"]["coordinates"]

print("\n⚡ Lightning Summary")
print("━" * 36)
print(f"Date:              {date}")
print(f"Search area:       {radius} miles from {lat}, {lon}")
print(f"Total strikes:     {data['resultsCount']}")
print(f"Cloud-to-ground:   {total_cg} ({summary['positiveStrikes']} positive, {summary['negativeStrikes']} negative)")
print(f"Closest strike:    {closest_lat:.4f}, {closest_lon:.4f}")
print(f"Closest time:      {closest['properties']['date']}")
```

```csharp title="C#"
using System.Text.Json;

var apiKey = "{YOUR_API_KEY}";
var lat = 28.37;
var lon = -81.57;
var radius = 20;
var date = "10/27/2025";

// Step 1: Fetch historical lightning data
using var client = new HttpClient();
var response = await client.GetStringAsync(
    $"https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey={apiKey}&q={lat},{lon}&distanceRadius={radius}&startDate={Uri.EscapeDataString(date)}");

using var doc = JsonDocument.Parse(response);

// Step 2: Summarize the activity
var resultsCount = doc.RootElement.GetProperty("resultsCount").GetInt32();
var summary = doc.RootElement.GetProperty("lightningSummary");
var positive = summary.GetProperty("positiveStrikes").GetInt32();
var negative = summary.GetProperty("negativeStrikes").GetInt32();
var totalCG = positive + negative;
var closest = summary.GetProperty("closestStrike").GetProperty("features")[0];
var closestLon = closest.GetProperty("geometry").GetProperty("coordinates")[0].GetDouble();
var closestLat = closest.GetProperty("geometry").GetProperty("coordinates")[1].GetDouble();
var closestDate = closest.GetProperty("properties").GetProperty("date").GetString();

Console.WriteLine("\n⚡ Lightning Summary");
Console.WriteLine(new string('━', 36));
Console.WriteLine($"Date:              {date}");
Console.WriteLine($"Search area:       {radius} miles from {lat}, {lon}");
Console.WriteLine($"Total strikes:     {resultsCount}");
Console.WriteLine($"Cloud-to-ground:   {totalCG} ({positive} positive, {negative} negative)");
Console.WriteLine($"Closest strike:    {closestLat:F4}, {closestLon:F4}");
Console.WriteLine($"Closest time:      {closestDate}");
```

```java title="Java"
import org.json.JSONObject;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.*;
import java.nio.charset.StandardCharsets;

public class LightningHistorical {
    public static void main(String[] args) throws Exception {
        String apiKey = "{YOUR_API_KEY}";
        double lat = 28.37, lon = -81.57;
        int radius = 20;
        String date = "10/27/2025";

        // Step 1: Fetch historical lightning data
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(
                "https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey="
                + apiKey + "&q=" + lat + "," + lon + "&distanceRadius=" + radius
                + "&startDate=" + URLEncoder.encode(date, StandardCharsets.UTF_8)))
            .build();

        HttpResponse<String> response =
            client.send(request, HttpResponse.BodyHandlers.ofString());

        // Step 2: Summarize the activity
        var doc = new JSONObject(response.body());
        var resultsCount = doc.getInt("resultsCount");
        var summary = doc.getJSONObject("lightningSummary");
        var positive = summary.getInt("positiveStrikes");
        var negative = summary.getInt("negativeStrikes");
        var totalCG = positive + negative;
        var closest = summary.getJSONObject("closestStrike")
            .getJSONArray("features").getJSONObject(0);
        var coords = closest.getJSONObject("geometry").getJSONArray("coordinates");
        var closestDate = closest.getJSONObject("properties").getString("date");

        System.out.println("\n⚡ Lightning Summary");
        System.out.println("━".repeat(36));
        System.out.printf("Date:              %s%n", date);
        System.out.printf("Search area:       %d miles from %.2f, %.2f%n", radius, lat, lon);
        System.out.printf("Total strikes:     %d%n", resultsCount);
        System.out.printf("Cloud-to-ground:   %d (%d positive, %d negative)%n", totalCG, positive, negative);
        System.out.printf("Closest strike:    %.4f, %.4f%n", coords.getDouble(1), coords.getDouble(0));
        System.out.printf("Closest time:      %s%n", closestDate);
    }
}
```

```bash title="bash"
#!/bin/bash
API_KEY="{YOUR_API_KEY}"
LAT=28.37
LON=-81.57
RADIUS=20
DATE="10/27/2025"

# Step 1: Fetch historical lightning data
DATA=$(curl -s "https://apidev.accuweather.com/lightning/v1/historical/geoposition/radius?apikey=${API_KEY}&q=${LAT},${LON}&distanceRadius=${RADIUS}&startDate=$(printf %s "$DATE" | jq -sRr @uri)")

# Step 2: Summarize the activity
echo ""
echo "⚡ Lightning Summary"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "$DATA" | jq -r --arg date "$DATE" --arg lat "$LAT" --arg lon "$LON" --arg radius "$RADIUS" '
  "Date:              \($date)",
  "Search area:       \($radius) miles from \($lat), \($lon)",
  "Total strikes:     \(.resultsCount)",
  "Cloud-to-ground:   \(.lightningSummary.positiveStrikes + .lightningSummary.negativeStrikes) (\(.lightningSummary.positiveStrikes) positive, \(.lightningSummary.negativeStrikes) negative)",
  "Closest strike:    \(.lightningSummary.closestStrike.features[0].geometry.coordinates[1]), \(.lightningSummary.closestStrike.features[0].geometry.coordinates[0])",
  "Closest time:      \(.lightningSummary.closestStrike.features[0].properties.date)"
'
```

</CodeTabs>

---

## Next steps

- [Real-Time Lightning](/recipes/lightning-realtime) — monitor current strikes near a location
- [Lightning Forecast](/recipes/lightning-forecast) — check lightning probability for the next 2 hours
- [Lightning Parameters](/developers/lightning/parameters) — full API reference
