# Finding Large Amounts of Sensor Indexes (Bounding Box API Call)

**URL:** <https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688>\
**Category:** API\
**Created:** [October 13, 2023, 11:35pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688 "2023-10-13T23:35:00Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![PurpleAir](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/purpleair/32/176_2.png) [@PurpleAir](https://community.purpleair.com/u/PurpleAir)\
**Post date:** [October 13, 2023, 11:35pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/1 "2023-10-13T23:35:00Z")

</div>

> This article is related to the PurpleAir API. If you are unfamiliar with it, check out our [API Landing Page](https://community.purpleair.com/t/api-landing-page/7145) to get started.

Requesting data from the API requires using a device’s sensor index. You can [find a sensor index for an individual sensor using the map](https://community.purpleair.com/t/sensor-index/4000). However, when obtaining data across a large area, you can utilize a bounding box in conjunction with the API to obtain those sensor indexes.

In this post we’ll show how to construct a bounding box and use it in an API call to obtain a list of sensor indexes.

> At the current time, there is no way to obtain sensor indexes based on geographical boundaries, such as national or provincial borders. If this is an important feature for you, please make a post in our [feature request](https://community.purpleair.com/c/user-experience/feature-requests/25) category.

* * *

## A Bounding Box Example Using Colorado, USA

### Finding the Corners of our Bounding Box

In this example, an API call will be made to obtain all sensor indexes in the state of Colorado. This process requires two sets of coordinates to indicate the boundaries of our box, a northeast point, and a southeast point.

> The corners used MUST be the northwest and southeast points of the bounding box you wish to create. Using incorrect corners or mixing the two corners up are some of the most common errors in making bounding box API calls.

These points can be found with [Google Maps](https://maps.google.com). When a location on Google Maps is clicked, it will show the latitude and longitude of that location. In the image below, the red arrow is pointing at our desired location for this example. At the bottom of the image within the red circle, the the latitude and longitude for the selected point is shown. It has a latitude of 40.9971734, and a longitude of -109.045037. We’ll use these values for the northwest corner of our bounding box.

 ![Screenshot 2023-10-10 at 2.19.27 AM](https://us1.discourse-cdn.com/flex020/uploads/purpleair/original/2X/b/bd4258e6f8337609c13dbe48298ff613638935bf.jpeg)

Below, we’ve selected the bottom right corner of Colorado. This gives us a latitude of 37.003282, and a longitude of -102.035759. We’ll use these values for the southeast corner of our bounding box call.

 ![Screenshot 2023-10-10 at 2.23.32 AM](https://us1.discourse-cdn.com/flex020/uploads/purpleair/original/2X/7/791b8ddcf10089377a169da60f379dbe61b13f7e.jpeg)

Now we have the following points for our call:

- Northwest
  - latitude: 40.9971734
  - longitude: -109.045037

- Southeast
  - latitude: 37.003282
  - longitude: -102.035759

### Constructing an API Call Using Our Bounding Box

We can now use these to construct a bounding box call. Bounding box calls are currently not supported by the [Data Download Tool](https://community.purpleair.com/t/purpleair-data-download-tool/3787), so you’ll need to make the API call directly. However, we can use the API documentation to help us by using the boxes labeled “Send a Sample Request.”

You’ll want to go to the API documentation for the [Get Sensors Data endpoint](https://api.purpleair.com/#api-sensors-get-sensors-data). If you scroll down, you will see the following boxes. For this example, we have filled in the information we want for our request. In our case, we’ve selected the following fields to give us more information about the sensors:

- latitude
- longitude
- position\_rating
- location\_type
- last\_seen

However, just requesting one field per sensor is enough. If your bounding box is large, then requesting many fields will cause the cost of your bounding box call to rise dramatically.

We have also set the “max\_age” parameter to 0. This is important, because the bounding box call by default will only return sensors that have reported in the past seven days. However, by setting 0 we obtain information for any sensor that has ever reported in the state of Colorado. Further details on how to use the max\_age parameter are found in the [API Documentation](https://api.purpleair.com/#api-sensors-get-sensors-data).

 ![Screenshot 2023-10-10 at 2.43.54 AM](https://us1.discourse-cdn.com/flex020/uploads/purpleair/original/2X/a/a4c505ccfc5f7aa960c006bf2b6dd8afefa7ca1c.png)

### Sending Our API Call

Once all of the information is filled out, click “Send.” Following this, data will appear below like the following example. If you don’t receive any data back, examine the response for an error message. We also recommend verifying that you have the correct latitude and longitude for your request. The most common mistake made is accidentally mixing up latitude and longitude in the bounding box call.

 ![Screenshot 2023-10-10 at 3.33.10 AM](https://us1.discourse-cdn.com/flex020/uploads/purpleair/original/2X/a/ab1ff505fa3d438ec01fc7e2dd41910211df6721.png)

Once we have successfully completed the call, we can copy the text in the “Response” window, and use it to find the sensor indexes. Looking at the “fields,” we can see that “sensor\_index” is the first number listed in the data. So the sensor index for the first sensor in our request is 310, the sensor index for the second sensor is 314, etc. We can now use these sensor indexes to perform API calls.

We also have the fields we requested earlier to assist us. For example, we have the latitude and longitude for each sensor, and we can tell if these sensors are indoor or outdoor based on the location\_type.

* * *

## Learn More

Learn more about the [PurpleAir API](https://api.purpleair.com/)  
Learn more about [Making API Calls with the PurpleAir API](https://community.purpleair.com/t/making-api-calls-with-the-purpleair-api/180).  
Learn more about our [API Use Guidelines](https://community.purpleair.com/t/api-use-guidelines/1589).  
Learn more about [API History Field Descriptions](https://community.purpleair.com/t/api-history-fields-descriptions/4652)

---

<div class="post-metadata">

**Author:** ![Md\_Zahidul\_Islam](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/md_zahidul_islam/32/4017_2.png) [@Md\_Zahidul\_Islam](https://community.purpleair.com/u/Md_Zahidul_Islam)\
**Post date:** [November 16, 2023, 9:35pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/2 "2023-11-16T21:35:20Z")

</div>

the returned locations of the sensors are way different than the passed boundary locations. I tried nwlng=-121.75,nwlat= 37.42, selng= -114.52, selat=32.55. When I checked the locations of the returned sensors I got selected\_sensors[‘latitude’].max(), selected\_sensors[‘latitude’].min() = (62.34708, -40.87172). How is this possible? Can you please help?

---

<div class="post-metadata">

**Author:** ![Josh\_PurpleAir](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/josh_purpleair/32/2842_2.png) [@Josh\_PurpleAir](https://community.purpleair.com/u/Josh_PurpleAir)\
**Post date:** [November 17, 2023, 4:49pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/3 "2023-11-17T16:49:25Z")

</div>

The most common cause of bounding box errors is mixing up the coordinates for the corners. Are you able to provide the URL you used to send your API request?

---

<div class="post-metadata">

**Author:** ![Md\_Zahidul\_Islam](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/md_zahidul_islam/32/4017_2.png) [@Md\_Zahidul\_Islam](https://community.purpleair.com/u/Md_Zahidul_Islam)\
**Post date:** [November 17, 2023, 8:18pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/4 "2023-11-17T20:18:40Z")

</div>

Hi @Josh_PurpleAir @epcw thank you both for your reply. Here is my code

```auto
# the method
def get_sensorslist(nwlon, nwlat, selon, selat, saveloc=""):
    paheaders = {"X-API-Key": data_config.pa_params['read_key'],
                 "nwlng": str(nwlon),
                 "nwlat": str(nwlat),
                 "selng": str(selon),
                 "selat": str(selat)
                 }

    # Getting data
    try:
        # Request purple air API data
        print(f"Requesting purple air API sensors list location NW: {nwlat}, {nwlon} ... "
              f" to SE: {selat}, {selon}")

        # Perform the purple air API data request
        response = requests.get(data_config.pa_params['sensor_url'],
                                headers=paheaders,
                                params={'fields': 'name,model,location_type,private,latitude,longitude,'
                                                  'altitude,position_rating,last_modified,date_created'}
                                )
    except Exception as e:
        print(f"Unable perform purple-air API request. {e}")
        sys.exit(1)

    # writing to csv file
    if len(saveloc) > 0:
        content = json.loads(response.content)
        data = content["data"]
        columns = content["fields"]

        df = pd.DataFrame(data, columns=columns)
        df.to_csv(saveloc, index=False, header=True)

```

Here is the method call:  
get\_sensorslist(-114.52,37.42, -121.75, 32.55, saveloc=“pa\_sensors3.csv”)

I appreciate your help. thanks

---

<div class="post-metadata">

**Author:** ![epcw](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/epcw/32/1917_2.png) [@epcw](https://community.purpleair.com/u/epcw)\
**Post date:** [November 17, 2023, 8:49pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/5 "2023-11-17T20:49:05Z")

</div>

-114.52 is EAST of -121.75 Ergo can’t be your NW long

When you call get\_sensorslist(-121.75,37.42, -114.52, 32.55, saveloc=“pa\_sensors3.csv”) it works

---

<div class="post-metadata">

**Author:** ![epcw](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/epcw/32/1917_2.png) [@epcw](https://community.purpleair.com/u/epcw)\
**Post date:** [November 17, 2023, 8:50pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/6 "2023-11-17T20:50:19Z")

</div>

![image](https://us1.discourse-cdn.com/flex020/uploads/purpleair/original/2X/3/3a69f379d0c6be6cb5d05d3d2ecdb03da3ae7dcd.png)

---

<div class="post-metadata">

**Author:** ![epcw](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/epcw/32/1917_2.png) [@epcw](https://community.purpleair.com/u/epcw)\
**Post date:** [November 17, 2023, 8:51pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/7 "2023-11-17T20:51:01Z")

</div>

This tool is something I bookmark to test and make sure my API call is correct so I don’t go bonkers trying to find a typo in my python - [Loading...](https://api.purpleair.com/#api-sensors-get-sensors-data)

---

<div class="post-metadata">

**Author:** ![Md\_Zahidul\_Islam](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/md_zahidul_islam/32/4017_2.png) [@Md\_Zahidul\_Islam](https://community.purpleair.com/u/Md_Zahidul_Islam)\
**Post date:** [November 17, 2023, 8:58pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/8 "2023-11-17T20:58:18Z")

</div>

Thank you so much @epcw I am still confused about the lat lng. I am new in this area.

---

<div class="post-metadata">

**Author:** ![Md\_Zahidul\_Islam](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/md_zahidul_islam/32/4017_2.png) [@Md\_Zahidul\_Islam](https://community.purpleair.com/u/Md_Zahidul_Islam)\
**Post date:** [November 17, 2023, 9:03pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/9 "2023-11-17T21:03:23Z")

</div>

> [@epcw](#):
>
> -121.75,37.42, -114.52, 32.55,

@epcw okay the problem still exists - when I do df[‘latitude’].max(), df[‘latitude’].min() I am expecting values between 32.55 abd 37.42 but I get (79.99046, -69.540985) also the query returns 25992 sensors that does not look reasonable to me. Thanks.

---

<div class="post-metadata">

**Author:** ![Md\_Zahidul\_Islam](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/md_zahidul_islam/32/4017_2.png) [@Md\_Zahidul\_Islam](https://community.purpleair.com/u/Md_Zahidul_Islam)\
**Post date:** [November 17, 2023, 9:14pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/10 "2023-11-17T21:14:01Z")

</div>

I also noticed that my query returns index - 53, 77, 81, 182… that looks different than your results. I am wondering how is that possible?

---

<div class="post-metadata">

**Author:** ![epcw](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/epcw/32/1917_2.png) [@epcw](https://community.purpleair.com/u/epcw)\
**Post date:** [November 17, 2023, 9:19pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/11 "2023-11-17T21:19:20Z")

</div>

I’m returning 1111 sensors in your bounding box.

---

<div class="post-metadata">

**Author:** ![Md\_Zahidul\_Islam](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/md_zahidul_islam/32/4017_2.png) [@Md\_Zahidul\_Islam](https://community.purpleair.com/u/Md_Zahidul_Islam)\
**Post date:** [November 17, 2023, 9:21pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/12 "2023-11-17T21:21:31Z")

</div>

@epcw can you please share your url here. Thanks

---

<div class="post-metadata">

**Author:** ![epcw](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/epcw/32/1917_2.png) [@epcw](https://community.purpleair.com/u/epcw)\
**Post date:** [November 17, 2023, 9:23pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/13 "2023-11-17T21:23:26Z")

</div>

Correction: 2191 sensors.  
max latitude: 37.41438  
min latitude: 32.57017

GET [https://api.purpleair.com/v1/sensors?fields=latitude%2C%20longitude&nwlng=-121.75&nwlat=37.42&selng=-114.52&selat=32.55](https://api.purpleair.com/v1/sensors?fields=latitude%2C%20longitude&nwlng=-121.75&nwlat=37.42&selng=-114.52&selat=32.55) HTTP/1.1

---

<div class="post-metadata">

**Author:** ![epcw](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/epcw/32/1917_2.png) [@epcw](https://community.purpleair.com/u/epcw)\
**Post date:** [November 17, 2023, 9:24pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/14 "2023-11-17T21:24:42Z")

</div>

Here it is with all of your fields [https://api.purpleair.com/v1/sensors?fields=name%2Cmodel%2Clocation\_type%2Cprivate%2Clatitude%2Clongitude%2Caltitude%2Cposition\_rating%2Clast\_modified%2Cdate\_created&nwlng=-121.75&nwlat=37.42&selng=-114.52&selat=32.55](https://api.purpleair.com/v1/sensors?fields=name%2Cmodel%2Clocation_type%2Cprivate%2Clatitude%2Clongitude%2Caltitude%2Cposition_rating%2Clast_modified%2Cdate_created&nwlng=-121.75&nwlat=37.42&selng=-114.52&selat=32.55)

---

<div class="post-metadata">

**Author:** ![Md\_Zahidul\_Islam](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/md_zahidul_islam/32/4017_2.png) [@Md\_Zahidul\_Islam](https://community.purpleair.com/u/Md_Zahidul_Islam)\
**Post date:** [November 17, 2023, 9:26pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/15 "2023-11-17T21:26:41Z")

</div>

thats extremely wired. My coordinates are same how the returned results will be different?

---

<div class="post-metadata">

**Author:** ![Md\_Zahidul\_Islam](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/md_zahidul_islam/32/4017_2.png) [@Md\_Zahidul\_Islam](https://community.purpleair.com/u/Md_Zahidul_Islam)\
**Post date:** [November 17, 2023, 9:29pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/16 "2023-11-17T21:29:56Z")

</div>

> [@epcw](#):
>
> [https://api.purpleair.com/v1/sensors?fields=name%2Cmodel%2Clocation\_type%2Cprivate%2Clatitude%2Clongitude%2Caltitude%2Cposition\_rating%2Clast\_modified%2Cdate\_created&nwlng=-121.75&nwlat=37.42&selng=-114.52&selat=32.55](https://api.purpleair.com/v1/sensors?fields=name%2Cmodel%2Clocation_type%2Cprivate%2Clatitude%2Clongitude%2Caltitude%2Cposition_rating%2Clast_modified%2Cdate_created&nwlng=-121.75&nwlat=37.42&selng=-114.52&selat=32.55)

I run your url and get 2192 stations which is reasonable.

---

<div class="post-metadata">

**Author:** ![epcw](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/epcw/32/1917_2.png) [@epcw](https://community.purpleair.com/u/epcw)\
**Post date:** [November 17, 2023, 9:31pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/17 "2023-11-17T21:31:45Z")

</div>

Is your url being constructed correctly in your code snippet? try printing the url to screen when it’s being run so you can debug

---

<div class="post-metadata">

**Author:** ![Md\_Zahidul\_Islam](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/md_zahidul_islam/32/4017_2.png) [@Md\_Zahidul\_Islam](https://community.purpleair.com/u/Md_Zahidul_Islam)\
**Post date:** [November 17, 2023, 9:36pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/18 "2023-11-17T21:36:30Z")

</div>

> [@epcw](#):
>
> try printing the url to

I think the conversion of lng and lat to string was causing the issue. ☹

---

<div class="post-metadata">

**Author:** ![Md\_Zahidul\_Islam](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/md_zahidul_islam/32/4017_2.png) [@Md\_Zahidul\_Islam](https://community.purpleair.com/u/Md_Zahidul_Islam)\
**Post date:** [November 17, 2023, 9:36pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/19 "2023-11-17T21:36:49Z")

</div>

Thank you @epcw so much for your help

---

<div class="post-metadata">

**Author:** ![epcw](https://sea2.discourse-cdn.com/flex020/user_avatar/community.purpleair.com/epcw/32/1917_2.png) [@epcw](https://community.purpleair.com/u/epcw)\
**Post date:** [November 17, 2023, 9:47pm UTC](https://community.purpleair.com/t/finding-large-amounts-of-sensor-indexes-bounding-box-api-call/5688/20 "2023-11-17T21:47:34Z")

</div>

Glad things worked out.
