# How to Make Efficient API Calls

**URL:** <https://community.purpleair.com/t/how-to-make-efficient-api-calls/6906>\
**Category:** API\
**Created:** [November 6, 2023, 10:23pm UTC](https://community.purpleair.com/t/how-to-make-efficient-api-calls/6906 "2023-11-06T22:23:00Z")\
**Posts on this page:** 1\
**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:** [November 6, 2023, 10:23pm UTC](https://community.purpleair.com/t/how-to-make-efficient-api-calls/6906/1 "2023-11-06T22:23: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.

This article outlines many ways that you can reduce the points usage of your API calls. These can involve either lowering the base cost of the call, or avoiding querying unnecessary fields.

> Some of these tips or fields listed are only applicable to certain API endpoints

* * *

## Averaging Periods and Data Resolution

The easiest way you can reduce your point cost is by querying a larger averaging period. For example, changing a request from real-time to hourly results in 30 times less data points, and a similar change in cost.

* * *

## Modified Since

When querying real-time data from [Get Sensors Data](https://api.purpleair.com/#api-sensors-get-sensors-data) or [Get Members Data](https://api.purpleair.com/#api-groups-get-members-data), the “modified\_since” parameter can be used to only return data from sensors that have reported since a given timestamp. This can be used with the data\_time\_stamp for your last call to only receive newly reported data.

> The “modified\_since” parameter is based on when a sensor has last reported data, while the “[last\_modified](https://community.purpleair.com/t/how-to-make-efficient-api-calls/6906#fields-that-dont-update-often-5)” field contains information on when a sensors’s registration was last changed. Though similarly named, they operate differently.

For example, if we send a request to Get Sensors Data, the response should include an element of metadata called “data\_time\_stamp.” If we set the modified\_since parameter to the data\_time\_stamp of our last API call, then we will only receive data for sensors that have reported new data since the previous API call.

Note that data\_time\_stamp is different from the response’s “time\_stamp”. time\_stamp indicates the time when the response was sent, while data\_time\_stamp indicates when the response’s data is current until. To accurately obtain all new data since the previous response, you will want to use data\_time\_stamp and query the API every minute.

* * *

## Averaged Fields

Many fields, such as pm2.5\_atm or temperature, have an averaged form of the field as well as a and b channels available. For historical data fields where A and B channels are available, we always recommend querying the A and B channels separately and averaging the data locally.

This is because if a sensor with two laser counters has an issue with one laser counter, such as a bug that has crawled inside or a failed fan, you will be able to verify data quality by comparing the two channels. This verification process is important for historical data because a sensor’s [Confidence Score](https://community.purpleair.com/t/the-confidence-score/5193)––`confidence`––is not available as historical metadata; it is a current data point only.

Additionally, the points cost may be lower since averaged fields cost 2 points per row, while individual channel data is 1 point per row. If a sensor has only reported “temperature\_a”, but no data for “temperature\_b”, then requesting the averaged field “temperature,” will still deduct 2 points per row of data returned. However, requesting temperature\_a and temperature\_b separately will only deduct 1 point for temperature\_a per row of data returned. Since there is no data for temperature\_b, you will not be deducted any points for that field in the returned data.

> While many PurpleAir sensors report [two channels](https://community.purpleair.com/t/what-are-channel-a-and-channel-b/3643) of PM data, only a few can report two channels of temperature, humidity, and pressure data. Currently, no PurpleAir sensors can report two channels of VOC data.

* * *

## Group Calls

If you are querying real-time data for many sensors at once, the group endpoints allow you to query data from many sensors at once. This requires that you first [create a group](https://api.purpleair.com/#api-groups-create-group) and [add members to a group](https://api.purpleair.com/#api-groups-create-member). You can then obtain real-time data for all group members with a single request using the [Get Members Data](https://api.purpleair.com/#api-groups-get-members-data) endpoint.

This means that instead of the base cost being 1 point for every sensor you query, the base cost will instead only be 5 points for data from the entire group.

* * *

## Fields That Don’t Update Often

The following fields don’t change often, and typically don’t require frequent API calls.

The field last\_modified indicates when the registration for a sensor was last updated. You can keep track of this field for a sensor index, and only request registration-related information if the registration has been updated.

| Field Name | When It Changes |
| --- | --- |
| date\_created | This field will never change for a sensor index |
| position\_rating | The position rating only changes when a device is connected to a new WiFi network or has its registration modified. |
| hardware | The hardware detected by the sensor doesn’t change frequently, and typically only changes when a component fails |
| firmware\_version | This will change when a device is updated to a newer firmware version. Devices will automatically update when newer firmware becomes available |
| last\_modified | This indicates when the registration was last modified |
| name | This can be changed during registration |
| location\_type | This can be changed during registration |
| private | This can be changed during registration |
| latitude | This can be changed during registration |
| longitude | This can be changed during registration |
| altitude | This can be changed during registration |
| led\_brightness | This can be changed during registration |

&nbsp;

## Unused or Rarely Used Fields

| Field Name | Description |
| --- | --- |
| ozone1 | An extremely limited number of PurpleAir sensors have ever reported ozone data. At the time of writing, only five sensors can be seen on the map with the “Ozone (ppb)” data layer selected |
| icon | This is a flag reserved for future use to reference an icon for the sensor |
| pa\_latency | This field measures the round trip time taken to send air quality data to PurpleAir and receive a response in milliseconds |
| memory | This value is primarily used by PurpleAir for diagnostic information of sensors |
| analog\_input | This is the analog voltage on the ADC input of the PurpleAir sensor control board |
| confidence\_manual | We recommend using the confidence field instead, as it takes confidence\_manual into account |
| confidence\_auto | We recommend using the confidence field instead, as it takes confidence\_auto into account |
| primary\_id\_a | A legacy field from when PurpleAir used ThingSpeak |
| primary\_key\_a | A legacy field from when PurpleAir used ThingSpeak |
| secondary\_id\_a | A legacy field from when PurpleAir used ThingSpeak |
| secondary\_key\_a | A legacy field from when PurpleAir used ThingSpeak |
| primary\_id\_b | A legacy field from when PurpleAir used ThingSpeak |
| primary\_key\_b | A legacy field from when PurpleAir used ThingSpeak |
| secondary\_id\_b | A legacy field from when PurpleAir used ThingSpeak |
| secondary\_key\_b | A legacy field from when PurpleAir used ThingSpeak |

&nbsp;

## Calculatable Data

The following fields can be derived from other sensor data using formulas available on the PurpleAir community forums. They are still available on the API, but API users concerned about cost can also locally calculate these values

| Name | Source Equation |
| --- | --- |
| scattering\_coefficient | [Visibility Data Layers](https://community.purpleair.com/t/visibility-data-layers/154) |
| deciviews | [Visibility Data Layers](https://community.purpleair.com/t/visibility-data-layers/154) |
| visual\_range | [Visibility Data Layers](https://community.purpleair.com/t/visibility-data-layers/154) |

&nbsp;

## Learn More

[API Landing Page](https://community.purpleair.com/t/api-landing-page/7145)  
[Data Download Tool](https://community.purpleair.com/t/purpleair-data-download-tool/3787)  
[Making API Calls with the PurpleAir API](https://community.purpleair.com/t/making-api-calls-with-the-purpleair-api/180)
