Nanonets API enforces rate limits to ensure fair usage and maintain optimal performance for all users. Getting a 429 response code from our API means that you have reached our rate-limit.
The rate limit applies to all POST requests within the OCR Predict section, including:
- Prediction for Image URL
- Prediction for Image File
- Async Prediction for Image URL
- Async Prediction for Image File
What’s the difference between Sync Call and Async Call?
- Sync: Your files will get uploaded and processed, and you will see the results on the screen.
- Async: your files will get uploaded and processed at a later point in time (usually within 5 minutes). Recommended if you are processing a lot of large files (> 3 pages of PDFs)
With the rollout of rate limiting, customers who integrated with the Nanonets platform via API might start seeing a new HTTP error code 429
from the file processing APIs:
/api/v2/OCR/Model/<model_id>/LabelFile
/api/v2/OCR/Model/<model_id>/LabelUrls
This error is thrown when the rate limit threshold in a 1-minute window reaches the set rate limit per model.
Handling 429
When you receive a 429 Too Many Requests
response, it indicates that you've hit the rate limit for your API calls within the last 1 minute. Here's how you can handle it:
- Implement a Backoff Strategy: Start with a 30-second delay before retrying the request.
- Use Exponential Backoff: If you continue to receive
429
responses, increase the delay exponentially (e.g., 30s, 60s, 120s, etc.). - Monitor and Log: Track the occurrences of
429
responses to optimize your request patterns and avoid hitting the rate limit.
Sample Implementations
Python
import requests
import time
url = 'https://app.nanonets.com/api/v2/OCR/Model/REPLACE_MODEL_ID/LabelFile/'
data = {'file': open('REPLACE_IMAGE_PATH.jpg', 'rb')}
auth = requests.auth.HTTPBasicAuth('5a09c08f-50ec-11ee-8eb4-82b44427823b', '')
def send_request(data, delay=30):
response = requests.post(url, auth=auth, files=data)
if response.status_code == 429:
print(f"Rate limit hit. Retrying after {delay} seconds.")
time.sleep(delay)
return send_request(data, delay * 2) # Exponential backoff
return response
response = send_request(data)
print(response.text)
Node.js
var request = require('request');
var fs = require('fs');
const form_data = {
'modelId': 'REPLACE_MODEL_ID',
'file': fs.createReadStream('REPLACE_IMAGE_PATH.jpg'),
};
const options = {
url: 'https://app.nanonets.com/api/v2/OCR/Model/REPLACE_MODEL_ID/LabelFile/',
formData: form_data,
headers: {
'Authorization': 'Basic ' + Buffer.from('5a09c08f-50ec-11ee-8eb4-82b44427823b' + ':').toString('base64')
}
};
function sendRequest(options, delay = 30000) {
request.post(options, function (err, httpResponse, body) {
if (httpResponse && httpResponse.statusCode === 429) {
console.log(`Rate limit hit. Retrying after ${delay / 1000} seconds.`);
setTimeout(() => sendRequest(options, delay * 2), delay); // Exponential backoff
} else {
console.log(body);
}
});
}
sendRequest(options);
JavaScript (Fetch API)
function sendRequest(delay = 30000) {
var data = new FormData();
data.append('file', fileBlob); // This is file object
// data.append('base64_data', base64EncodedFile); // Can use this for base64 of the file
var xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", function () {
if (this.readyState === this.DONE) {
if (this.status === 429) {
console.log(`Rate limit hit. Retrying after ${delay / 1000} seconds.`);
setTimeout(() => sendRequest(delay * 2), delay); // Exponential backoff
} else {
console.log(this.responseText);
}
}
});
xhr.open("POST", "https://app.nanonets.com/api/v2/OCR/Model/{{model_id}}/LabelFile/");
xhr.setRequestHeader("authorization", "Basic " + btoa("5a09c08f-50ec-11ee-8eb4-82b44427823b:"));
xhr.send(data);
}
sendRequest();
Best Practices
- Optimize Requests: Reduce the number of API calls by using asynchronous processing where possible.
- Monitor Usage: Use logging and analytics to understand your usage patterns and adjust accordingly.
- Graceful Handling: Ensure your application can handle rate limiting gracefully without significant disruptions to user experience.
Implement these strategies to effectively manage rate limits and ensure smooth integration with our API platform.