Handle API Throttling


The Alexa Smart Properties (ASP) REST APIs limit the number of Transactions per Second (TPS) or requests per second that they can handle. Your code should account for this by properly handling HTTP 429 Request Throttled responses.

How to handle API throttling in your code

When a request to an API exceeds the TPS limit for that API, the API returns an HTTP 429 Request Throttled response. A throttled response is a valid state for the API and shouldn't be regarded as an error.

Amazon recommends that you code defensively and handle the throttled response gracefully. Your code to handle 429 responses and retry API calls shouldn't depend on the specific TPS limit for a particular API. Good code can ignore the TPS limits and use the same algorithm across all the ASP APIs.

For example, manage requests that return a 429 as follows:

  • Use a try/catch structure to retry the request and catch errors. Handle other errors appropriately, such as with notifications or throwing exceptions upstream.
  • If the response code indicates a successful call (usually 200 or 202), use the response normally.
  • If the response code is 429, retry after waiting for a sleep period and increment the retry count.
  • Increment your sleep period by doubling it every retry
  • Have a maximum number of retries and stop retires after this max retry count

Sample code to handle 429 responses

The following code example shows a request manager function (getAPIResponse) that implements retry code.

Copied to clipboard.

import axios from 'axios';

export const apiSettings = 
{
  apiDelay : 1000,
  baseURL : 'https://api.amazonalexa.com',
  backoff: "2000,3000,5000,8000,13000,21000"
}

function apiCallDelay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

let backoff;

//config is an axios config object
export async function getAPIResponse(config, backoffIndex) {

  if (backoffIndex === undefined && apiSettings.backoff.length > 0) {
    backoff = apiSettings.backoff.split(',');
    backoffIndex = 0;
  }

  let res = null;
  try {
    res = await axios(config);
    await apiCallDelay(apiSettings.apiDelay);
    if (res.data) {
      return res.data;
    }
    return{statuscode: res.status};
  } catch (err) {
    
    if (err.response?.status)
    {
      //429 TOO_MANY_REQUESTS
      if ([503,500,429].includes(err.response.status)) {
        if (backoffIndex < backoff.length) {
          await apiCallDelay(backoff[backoffIndex]);
          return getAPIResponse(config, backoffIndex + 1);
        }
      }
      res = err.response.data;
      res.statuscode = err.response.status;
    } else if (err.response && (typeof err.response.data) === 'string') {
      // api does not return json data
      res = { statuscode : err.response.status};
    } 
      else 
    {
      res = { code : err.code};
    }

    return res;
  } 
}

TPS limits for the ASP REST APIs

The table in this section summarizes the TPS limits for the ASP REST APIs. These details are provided to help set expectations for API behavior. However, as noted earlier, don't rely on these specific limits or reference them in code.

The table refers to the following concepts:

  • Shared TPS – The number of transactions per second is shared across all customers that call that API operation at the same time. For example, assume the shared TPS of an API is 10. When one customer calls the API at five TPS, there is only five more TPS available for other customers.
  • Shared across operations – Some APIs share the TPS across a suite of API operations instead of each individual operation. For example, the TPS limit for reminders is applied against the sum of POST /v2/alerts/reminders, GET /v2/alerts/reminders/{reminderId}, PUT /v2/alerts/reminders/{reminderId}, and DELETE /v2/alerts/reminders/{reminderId}.

    The Notes column indicates whether an API operation shares TPS across other operations.

  • Limits that depend on configuration – Some APIs have a TPS limit that depends on the parameters of the API or the configuration of the property. For example, the /v1/addressBooks/{addressBookId}/contacts call to create or delete contacts in address books has a TPS limit divided by the number of units associated with the address book. If an address book is associated with 20 rooms, the TPS limit for adding or deleting a contact in this address book is 15/20 = 0.75.

    The Notes column describes the configuration details that can change the TPS for a given API operation.

API operation Units per API request NA TPS limit Shared TPS Notes

Analytics API

Generate Report

POST /v1/enterprise/analytics/reports

0.33

10

No

3 requests for every 15 minutes

Certificate Authority Management API Reference

Delete certificate authority

DELETE /v1/enterprise/certificateAuthorities/{certificateAuthorityId}

1.0

10

Yes

Get all certificate authorities

GET /v1/enterprise/certificateAuthorities?nextToken={nextToken}&maxResults={maxResults}

1.0

20

Yes

Get all certificate authorities (expand all)

GET /v1/enterprise/certificateAuthorities?nextToken={nextToken}&maxResults={maxResults}&expand=all

1.0

10

Yes

Get certificate authority details

GET /v1/enterprise/certificateAuthorities/{certificateAuthorityId}

1.0

50

Yes

Get certificate authority details (expand all)

GET /v1/enterprise/certificateAuthorities/{certificateAuthorityId}?expand=all

1.0

10

Yes

Communications API

Create a communication profile

POST /v1/communications/profile

1

20

No

Global limit of 20 TPS across all clients

Create a contact

POST /v1/addressBooks/{addressBookId}/contacts

1

10

No

Global limit of 100 TPS across all clients. TPS for operations on address books are divided by the number of units currently associated with the address book. If an address book is currently associated with 20 rooms, the TPS limit for adding or deleting a contact in this address book is 10/20 = 0.50.

Create a reciprocal association

POST /v1/communications/profile/{profileId}/reciprocalAssociations

1

20

No

Global limit of 20 TPS

Create address book associations in bulk

POST /v1/addressBooks/{addressBookId}/unitAssociations/batch

100.0

2

Yes

Create address book associations in bulk

POST /v1/addressBooks/{addressBookId}/unitAssociations/batch

100

2

Yes

Create an address book

POST /v1/addressBooks

1

40

No

Global limit of 100 TPS across all clients

Create an address book association

POST /v1/addressBooks/{addressBookId}/unitAssociations

1

10

No

Create blocking rule

PUT /v1/communications/profile/{profileId}/contacts/settings/Block?alexaCommunicationProfileId={alexaCommunicationProfileId}

1

5

No

Create communication profiles in bulk

POST /v1/communications/profiles/batch

100.0

2

Yes

Create contacts in bulk

POST /v1/addressBooks/{addressBookId}/contacts/batch

100.0

2

Yes

Create contacts in bulk

POST /v1/addressBooks/{addressBookId}/contacts/batch

100

2

Yes

Delete a communication profile

DELETE /v1/communications/profile/{profileId}

1

20

No

Global limit of 20 TPS across all clients

Delete a contact

DELETE /v1/addressBooks/{addressBookId}/contacts/{contactId}

1

10

No

Global limit of 15 TPS across all clients

Delete a reciprocal association status

DELETE /v1/communications/profile/{profileId}/reciprocalAssociations?contactId={contactId}

1

20

No

Global limit of 20 TPS

Delete an address book

DELETE /v1/addressBooks/{addressBookId}

1

40

No

Global limit of 100 TPS across all clients

Delete an address book association

DELETE /v1/addressBooks/{addressBookId}/unitAssociations

1

10

No

Get a communication profile by entity id

GET /v1/communications/profile?entity.type={entity.type}&entity.id={entity.id}

1

20

No

Global limit of 20 TPS across all clients

Get a communication profile by profileId

GET /v1/communications/profile/{profileId}

1

20

No

Global limit of 20 TPS across all clients

Get a contact

GET /v1/addressBooks/{addressBookId}/contacts/{contactId}

1

30

No

Global limit of 15 TPS across all clients

Get an address book

GET /v1/addressBooks/{addressBookId}

1

40

No

Global limit of 100 TPS across all clients

Get an address book association

GET /v1/addressBooks/{addressBookId}/unitAssociations

1

10

No

Get blocking rule

GET /v1/communications/profile/{profileId}/contacts/settings/Block?value={value}

1

5

No

Get drop-in preference

GET /v1/communications/profile/{sourceProfileId}/contacts/settings/DropIn?alexaCommunicationProfileId={alexaCommunicationProfileId}

1

5

No

Get reciprocal association status

GET /v1/communications/profile/{profileId}/reciprocalAssociations?contactId={contactId}

1

20

No

Global limit of 20 TPS

List address book associations for a unit

GET /v1/addressBooks/unitAssociations

1

10

No

List address books

GET /v1/addressBooks

1

40

No

Global limit of 100 TPS across all clients

List contacts

GET /v1/addressBooks/{addressBookId}/contacts

1

10

No

Global limit of 15 TPS across all clients

Set drop-in preference

PUT /v1/communications/profile/{sourceProfileId}/contacts/settings/DropIn?alexaCommunicationProfileId={alexaCommunicationProfileId}

1

5

No

Update a contact

PUT /v1/addressBooks/{addressBookId}/contacts/{contactId}

1

10

No

Global limit of 15 TPS across all clients

Update an address book

PUT /v1/addressBooks/{addressBookId}

1

40

No

Global limit of 100 TPS across all clients

Endpoint Features API

All GET operations

All operations with a URI that begins with: GET /v2/endpoints/{endpointId}/features/, unless otherwise noted.

For example, GET /v2/endpoints/{endpointId}/features/bluetooth

1.0

50

No

All POST operations

All operations with a URI that begins with: POST /v2/endpoints/{endpointId}/features/, unless otherwise noted.

For example, POST /v2/endpoints/{endpointId}/features/bluetooth/unpair

1.0

50

No

Endpoint Wi-Fi Management API

Get Wi-Fi installation status

GET /v2/endpoints/{endpointId}/features/connectivity/addOrUpdateWifiConfigurations/submittedOperations/{operationId}

1.0

100

No

Set Wi-Fi configurations

POST /v2/endpoints/{endpointId}/features/connectivity/addOrUpdateWifiConfigurations

1.0

100

Yes

After 20 TPS, requests take longer to complete.

Endpoints API

All GET operations

All operations with a URI that begins with: GET /v2/endpoints, unless otherwise noted.

For example, GET /v2/endpoints?owner={owner}&expand={expand}&maxResults={maxResults}&nextToken={nextToken}

1.0

100

No

Forget endpoint

POST /v2/endpoints/{endpointId}/forget

1.0

15

No

Get endpoint by ID

GET /v2/endpoints/{endpointId}?expand={expand}

1.0

50

No

Update associated units

PUT /v2/endpoints/{endpointId}/associatedUnits

1.0

15

No

Update friendly name

POST /v2/endpoints/{endpointId}/friendlyName

1.0

50

No

Event Messenger API

Create a subscription

POST /v1/eventMessenger/subscriptions

1.0

10

No

Create a subscription configuration

POST /v1/eventMessenger/subscriptionConfigurations

1.0

10

No

Delete a subscription configuration

DELETE /v1/eventMessenger/subscriptionConfigurations/{id}

1.0

10

No

Delete subscription

DELETE /v1/eventMessenger/subscriptions/{id}

1.0

10

No

Get a subscription by ID

GET /v1/eventMessenger/subscriptions/{id}

1.0

30

No

Get a subscription configuration by ID

GET /v1/eventMessenger/subscriptionConfigurations/{id}

1.0

30

No

Get subscription configurations

GET /v1/eventMessenger/subscriptionConfigurations

1.0

30

No

Get subscriptions

GET /v1/eventMessenger/subscriptions

1.0

30

No

Notifications API

Send notifications

POST /v3/notifications

100.0

3

No

TPS increases if the number of units decreases. You can create notifications for 300 units per second.

Proactive Suggestion API

Create a campaign

POST /v1/proactive/campaigns

100.0

3

No

TPS increases if the number of units decreases. You can create notifications for 300 units per second.

Property Hierarchy Management API

Create a unit

POST /v2/units

1.0

30

Yes

Reminders API

Create a reminder

POST /v2/alerts/reminders

1.0

10

Yes

All reminder APIs have one shared pool of TPS which is in total 50 TPS

Delete a reminder

DELETE /v2/alerts/reminders/{reminderId}

1.0

10

Yes

All reminder APIs have one shared pool of TPS which is in total 50 TPS

Get a reminder

GET /v2/alerts/reminders/{reminderId}

1.0

10

Yes

All reminder APIs have one shared pool of TPS which is in total 50 TPS

Update a reminder

PUT /v2/alerts/reminders/{reminderId}

1.0

10

Yes

All reminder APIs have one shared pool of TPS which is in total 50 TPS

Skill Management API

Enable a skill for multiple units

POST /v1/skills/{skillId}/enablements/batch

100

2

No


Was this page helpful?

Last updated: frontmatter-missing