# Throttling API calls and preventing 429 error

**URL:** https://forums.knack.com/t/throttling-api-calls-and-preventing-429-error/6987
**Category:** Ask Developers
**Created:** [August 10, 2018, 12:51pm UTC](https://forums.knack.com/t/throttling-api-calls-and-preventing-429-error/6987 "2018-08-10T12:51:13Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![Christophe07388](https://avatars.discourse-cdn.com/v4/letter/c/9fc348/32.png) [@Christophe07388](https://forums.knack.com/u/Christophe07388)
#### Post date: [August 10, 2018, 12:51pm UTC](https://forums.knack.com/t/throttling-api-calls-and-preventing-429-error/6987/1 "2018-08-10T12:51:13Z")

</div>

My application has a Javascript function that makes a copy of an existing set of records that is shown on the screen in a table. I accomplish this by looping through the data model and making object-based API calls to POST data back to Knack. The problem is that the 10 calls/1 second limit is quickly encountered and results in partial copies of data when records are missed.

Knack documentation has pseudo-code that shows (in theory) how a sleep/wait function could delay things but I cannot for the life of me figure out how to throttle my requests. Should I be using some type of retry logic instead each time it fails? If so, how would I accomplish this? Here's a sample of my data:

Knack.showSpinner();  
   
 // Get table data  
 var data\_view\_287 = Knack.models['view\_287'].data.toJSON();

// \*\*\*\*\*\*\*\*\*\*\*\* Loop through Dispatch Details table   
 for(x = 0; x \< data\_view\_287.length; x++){  
   
item = data\_view\_287[x];

var objJSON = {  
 field\_250: record.id,  
 field\_245: item.field\_245\_raw[0].id,  
 field\_261: item.field\_261,  
 field\_280: item.field\_280,  
 field\_242: item.field\_242,  
 field\_243: item.field\_243,  
 field\_246: item.field\_246\_raw[0].id,   
 field\_247: item.field\_247,   
 field\_248: item.field\_248,   
 field\_286: item.field\_286  
 }

// POST to Records  
 $.ajax({  
   
 url: '[https://api.knack.com/v1/objects/object\_99/records](https://api.knack.com/v1/objects/object_99/records)',  
 type: 'POST',  
 headers: {  
 'Authorization': Knack.getUserToken(),  
 'X-Knack-Application-Id': Knack.application\_id,  
 'X-Knack-REST-API-Key': 'not-shown',  
 'Content-Type': 'application/json'  
 },  
 data: JSON.stringify(objJSON),  
 success: function(records) {  
 }  
   
 }); //End POST  
   
   
 } //End For-loop

Knack.hideSpinner();

---

<div class="post-metadata">

### Author: ![DavideAgno21569](https://avatars.discourse-cdn.com/v4/letter/d/e0b2c6/32.png) [@DavideAgno21569](https://forums.knack.com/u/DavideAgno21569)
#### Post date: [September 6, 2019, 9:15am UTC](https://forums.knack.com/t/throttling-api-calls-and-preventing-429-error/6987/2 "2019-09-06T09:15:30Z")

</div>

I want to add something here, also because I have observed some behaviour with the knack API which I don't fully understand.

The scenario: I have two tables(A and B) from two different objects. Both those tables has a checkbox. When I press the button for each checked box of table B I create a new record connected to the checked object B with a field named with the object checked with table A. This means that if I select 10 objects from A and 10 Objects from B, I am creating 100 connected records ad once.  
  
Now, first of all, for the benefit of testing, I've created this scene and I realized that I was not getting any 429 error. The calls were supposedly launched almost all together and slowly slowly the results were getting back and the records were created.

I thought that knack API had a sort of cache / queue so after the 10 calls per second limit was putting the other on hold. regardless, the more the time was passing the less the results were coming (for example, I got the first 40 results in about 45 seconds, and the other 60 in minutes). Even if I was not getting any error, I was totally generating a sort of delay (I'm talking about VIEW based requests since everything is in the Javaascript and I'm not happy to expose my API key).

So, without any error to intercept, I thought about throttling the API requests in ADVANCE. How? With a deferred execution. I'm basically counting the number of iterations, every 10 I delay the execution by 1 second. Meaning: the first 10 are executed at second "0", the next at second "1" and so on. So I am sure that the request from 90 to 100 are executed about 10 seconds AFTER I hit the button.

Do you think this approach makes sense ? Following the code I am using

```
$("#bulk").click(function(){

// calculate total number of requests
var count = ($('#view_xxx tbody input[type=checkbox]:checked').length)*($('#view_yyy tbody input[type=checkbox]:checked').length);
var ctr = 0;
var ctr2 = 0;
$('#view_XXX tbody input[type=checkbox]:checked').each(function(i) {

//obmitted code that works with data

$('#view_380 tbody input[type=checkbox]:checked').each(function() {

//obmitted code that preapers all api Headers and Data

ctr++;
var timeout = Math.floor(ctr2 / 10) *1000; // this gives the milliseconds that I have to delay
setTimeout(function(){
$.ajax({
url: api_url,
headers: headers,
type: 'POST',
data: JSON.stringify(data),
complete: function(){ ctr2 ++; } // this is another counter that tells me when all the requests are done
}).done(function(responseData){ console.log(responseData); }); // This is where to check the response
},timeout);
});
});
});
```

---

<div class="post-metadata">

### Author: ![Christophe07388](https://avatars.discourse-cdn.com/v4/letter/c/9fc348/32.png) [@Christophe07388](https://forums.knack.com/u/Christophe07388)
#### Post date: [August 13, 2018, 2:23pm UTC](https://forums.knack.com/t/throttling-api-calls-and-preventing-429-error/6987/3 "2018-08-13T14:23:52Z")

</div>

That's perfect!!! Thanks so much for sharing that. I've been trying workarounds for the past few weeks that were overly complicated and not accomplishing what I was looking for. You saved the day.

---

<div class="post-metadata">

### Author: ![BradStevens](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.knack.com/bradstevens/32/140_2.png) [@BradStevens](https://forums.knack.com/u/BradStevens)
#### Post date: [August 10, 2018, 11:04pm UTC](https://forums.knack.com/t/throttling-api-calls-and-preventing-429-error/6987/4 "2018-08-10T23:04:47Z")

</div>

Hi Christopher,

We've had success catching this error and re-trying within ajax calls using the error handler. A good example is here [https://stackoverflow.com/questions/10024469/whats-the-best-way-to-retry-an-ajax-request-on-failure-using-jquery](https://stackoverflow.com/questions/10024469/whats-the-best-way-to-retry-an-ajax-request-on-failure-using-jquery).

Below is the code adopted from that, and using a retryLimit of 3 seems about right for our apps.

```
$.ajax({
    url : 'someurl',
    type : 'POST',
    data : ....,   
    tryCount : 0,
    retryLimit : 3,
    success : function(json) {
        //do something
    },
    error : function(request, status, error ) {
        if (request.status == 429) {
            this.tryCount++;
            if (this.tryCount <= this.retryLimit) {
                console.log('try again...');
                $.ajax(this);
                return;
            } else { console.log('update failed!'); }
        } else {
            //handle other errors
        }
    }
});
```

---

<div class="post-metadata">

### Author: ![BradStevens](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.knack.com/bradstevens/32/140_2.png) [@BradStevens](https://forums.knack.com/u/BradStevens)
#### Post date: [November 19, 2023, 10:37pm UTC](https://forums.knack.com/t/throttling-api-calls-and-preventing-429-error/6987/5 "2023-11-19T22:37:25Z")

</div>

A 2023 update - now that the API is far more responsive (a good thing) we’re finding the retryLimit of around 10 to be optimal now.
