# Recipe: Location Search

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>
);

Most AccuWeather weather endpoints (current conditions, forecasts, alerts, etc.) require a **LocationKey** — a unique numeric identifier for a specific location. This recipe shows you how to look up that key before making your first weather request.

:::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

> "I want to display weather for New York City. How do I get the LocationKey I need?"

---

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

<AccordionItem value="step-1">
  <AccordionTrigger><StepHeader n={1}>Search by city name</StepHeader></AccordionTrigger>
  <AccordionContent>

Call the city search endpoint with a text query. The API returns an array of matching locations ranked by relevance.

**Endpoint:**
```
GET https://apidev.accuweather.com/locations/v1/cities/search.json?apikey={YOUR_API_KEY}&q=New York
```

<CodeTabs syncKey="language">

```ts title="TypeScript"
const apiKey = "{YOUR_API_KEY}";
const query = "New York";

const response = await fetch(
  `https://apidev.accuweather.com/locations/v1/cities/search.json?apikey=${apiKey}&q=${encodeURIComponent(query)}`
);
const locations: Record<string, any>[] = await response.json();
```

```python title="Python"
import requests

api_key = "{YOUR_API_KEY}"
query = "New York"

response = requests.get(
    "https://apidev.accuweather.com/locations/v1/cities/search.json",
    params={"apikey": api_key, "q": query},
)
locations = response.json()
```

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

var apiKey = "{YOUR_API_KEY}";
var query = "New York";
var url = $"https://apidev.accuweather.com/locations/v1/cities/search.json?apikey={apiKey}&q={Uri.EscapeDataString(query)}";
var response = await client.GetAsync(url);
var data = await response.Content.ReadAsStringAsync();
```

```java title="Java"
HttpClient client = HttpClient.newHttpClient();
String apiKey = "{YOUR_API_KEY}";
String query = "New York";
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://apidev.accuweather.com/locations/v1/cities/search.json?apikey="
        + apiKey + "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8)))
    .build();

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

```bash title="bash"
curl "https://apidev.accuweather.com/locations/v1/cities/search.json?apikey={YOUR_API_KEY}&q=New+York"
```

</CodeTabs>

  </AccordionContent>
</AccordionItem>

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

The API returns an array of location objects. The first result is usually the best match.

```json
[
  {
    "Version": 1,
    "Key": "349727",
    "Type": "City",
    "Rank": 15,
    "LocalizedName": "New York",
    "Country": {
      "ID": "US",
      "LocalizedName": "United States"
    },
    "AdministrativeArea": {
      "ID": "NY",
      "LocalizedName": "New York"
    },
    "TimeZone": {
      "Code": "EDT",
      "GmtOffset": -4,
      "IsDaylightSaving": true
    },
    "GeoPosition": {
      "Latitude": 40.779,
      "Longitude": -73.969,
      "Elevation": {
        "Metric": { "Value": 37, "Unit": "m", "UnitType": 5 },
        "Imperial": { "Value": 121, "Unit": "ft", "UnitType": 0 }
      }
    },
    "DataSets": [
      "AirQualityCurrentConditions",
      "Alerts",
      "FutureRadar",
      "MinuteCast",
      "Radar"
    ]
  }
]
```

:::tip

The `Key` field (`"349727"`) is the **LocationKey** you'll pass to all downstream weather endpoints.

:::

  </AccordionContent>
</AccordionItem>

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

<CodeTabs syncKey="language">

```ts title="TypeScript"
const locationKey = locations[0].Key;
console.log(`LocationKey: ${locationKey}`);
// → "349727"
```

```python title="Python"
location_key = locations[0]["Key"]
print(f"LocationKey: {location_key}")
# → "349727"
```

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

var doc = JsonDocument.Parse(data);
var locationKey = doc.RootElement[0].GetProperty("Key").GetString();
Console.WriteLine($"LocationKey: {locationKey}");
// → "349727"
```

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

var locations = new JSONArray(data);
var locationKey = locations.getJSONObject(0).getString("Key");
System.out.println("LocationKey: " + locationKey);
// → "349727"
```

```bash title="bash"
echo "$DATA" | jq -r '.[0].Key'
# → "349727"
```

</CodeTabs>

  </AccordionContent>
</AccordionItem>

</Accordion>

---

## Key response fields

| Field | Type | Description |
|-------|------|-------------|
| `Key` | String | The LocationKey — save this for all weather requests |
| `LocalizedName` | String | Human-readable city name |
| `Country.ID` | String | ISO 3166-1 alpha-2 country code |
| `AdministrativeArea.ID` | String | State/province/region code |
| `Rank` | Integer | Lower = more prominent location (1–500+) |
| `DataSets` | Array | Which APIs are available for this location |
| `GeoPosition` | Object | Latitude, longitude, and elevation |

---

## Alternative search methods

**By postal code:**
```bash
curl "https://apidev.accuweather.com/locations/v1/postalcodes/search.json?apikey={YOUR_API_KEY}&q=10001"
```

**By coordinates (lat/lon):**
```bash
curl "https://apidev.accuweather.com/locations/v1/cities/geoposition/search.json?apikey={YOUR_API_KEY}&q=40.7143,-74.006"
```

**Autocomplete (for search-as-you-type UIs):**
```bash
curl "https://apidev.accuweather.com/locations/v1/cities/autocomplete.json?apikey={YOUR_API_KEY}&q=New+Yo"
```

---

## Common pitfalls

:::warning

**Too many results?** Add the `countryCode` parameter to narrow results to a specific country:
```
&q=Springfield&countryCode=US
```

:::

:::note

**`DataSets` matters** — if `MinuteCast` or `Alerts` is not in the `DataSets` array, those APIs won't return data for this location.

:::

---

## Complete code sample

Copy a full, runnable example that searches for a location and extracts its LocationKey.

<CodeTabs syncKey="language">

```ts title="TypeScript"
const API_KEY = "{YOUR_API_KEY}";
const query = "New York";

// Step 1: Search by city name
const res = await fetch(
  `https://apidev.accuweather.com/locations/v1/cities/search.json?apikey=${API_KEY}&q=${encodeURIComponent(query)}`
);
const locations: Record<string, any>[] = await res.json();

// Step 2: Extract the top result's key
const top = locations[0];
const locationKey = top.Key;

// Step 3: Print the result
console.log(`Top match for "${query}":`);
console.log(`  City:        ${top.LocalizedName}`);
console.log(`  Country:     ${top.Country.LocalizedName}`);
console.log(`  LocationKey: ${locationKey}`);
```

```python title="Python"
import requests

API_KEY = "{YOUR_API_KEY}"
query = "New York"

# Step 1: Search by city name
resp = requests.get(
    "https://apidev.accuweather.com/locations/v1/cities/search.json",
    params={"apikey": API_KEY, "q": query},
)
locations = resp.json()

# Step 2: Extract the top result's key
top = locations[0]
location_key = top["Key"]

# Step 3: Print the result
print(f'Top match for "{query}":')
print(f"  City:        {top['LocalizedName']}")
print(f"  Country:     {top['Country']['LocalizedName']}")
print(f"  LocationKey: {location_key}")
```

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

var apiKey = "{YOUR_API_KEY}";
var query = "New York";

// Step 1: Search by city name
using var client = new HttpClient();
var response = await client.GetStringAsync(
    $"https://apidev.accuweather.com/locations/v1/cities/search.json?apikey={apiKey}&q={Uri.EscapeDataString(query)}");

using var doc = JsonDocument.Parse(response);

// Step 2: Extract the top result's key
var top = doc.RootElement[0];
var name = top.GetProperty("LocalizedName").GetString();
var country = top.GetProperty("Country").GetProperty("LocalizedName").GetString();
var locationKey = top.GetProperty("Key").GetString();

// Step 3: Print the result
Console.WriteLine($"Top match for \"{query}\":");
Console.WriteLine($"  City:        {name}");
Console.WriteLine($"  Country:     {country}");
Console.WriteLine($"  LocationKey: {locationKey}");
```

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

public class LocationSearch {
    public static void main(String[] args) throws Exception {
        String apiKey = "{YOUR_API_KEY}";
        String query = "New York";

        // Step 1: Search by city name
        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(
                "https://apidev.accuweather.com/locations/v1/cities/search.json?apikey="
                + apiKey + "&q=" + URLEncoder.encode(query, StandardCharsets.UTF_8)))
            .build();

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

        var locations = new JSONArray(response.body());

        // Step 2: Extract the top result's key
        var top = locations.getJSONObject(0);
        String name = top.getString("LocalizedName");
        String country = top.getJSONObject("Country").getString("LocalizedName");
        String locationKey = top.getString("Key");

        // Step 3: Print the result
        System.out.println("Top match for \"" + query + "\":");
        System.out.println("  City:        " + name);
        System.out.println("  Country:     " + country);
        System.out.println("  LocationKey: " + locationKey);
    }
}
```

```bash title="bash"
#!/bin/bash
API_KEY="{YOUR_API_KEY}"
QUERY="New York"

# Step 1: Search by city name
DATA=$(curl -s --get \
  --data-urlencode "apikey=${API_KEY}" \
  --data-urlencode "q=${QUERY}" \
  "https://apidev.accuweather.com/locations/v1/cities/search.json")

# Step 2: Extract the top result's key and context
NAME=$(echo "$DATA" | jq -r '.[0].LocalizedName')
COUNTRY=$(echo "$DATA" | jq -r '.[0].Country.LocalizedName')
KEY=$(echo "$DATA" | jq -r '.[0].Key')

# Step 3: Print the result
echo "Top match for \"${QUERY}\":"
echo "  City:        ${NAME}"
echo "  Country:     ${COUNTRY}"
echo "  LocationKey: ${KEY}"
```

</CodeTabs>

---

## Next steps

With your LocationKey in hand, continue to:

- [Current Conditions](/recipes/current-conditions) — get real-time weather right now
- [Hourly Forecast](/recipes/hourly-forecast) — hour-by-hour precipitation and temperature
- [5-Day Daily Forecast](/recipes/daily-forecast) — daily highs, lows, and conditions
