Do Explo’s API endpoints have a rate limit?

Yes. Currently our rate limit for https://api.explo.co/ is set to 180 requests per minute across all endpoints, on a requestor IP basis. This was updated on February 19, 2025 from 600 requests per minute to ensure healthy API hygiene and prevent adversarial actions.

There is an additional cap on the API endpoint used to ad hoc export dashboard PDFs. This endpoint should not be called programmatically, rather it is only called by the Explo application itself. It is being called out in the docs for completeness. The cap for https://api.explo.co/embed/export/dashboard/pdf is set to 20 requests per 10 minutes per requestor IP.

Other specific endpoints may have more restrictive rate limits and can be adjusted in the future. Requests made when over quota will receive an HTTP 429 error code with a descriptive message.

If you would like a bulk API endpoint, please reach out to the Explo support team.

Example Code Snippet to Handle HTTP 429s

Below is some code examples you can use to directionally help you navigate how to check for HTTP 429 error codes and ease off the API until the rate limit resets.

JavaScript, Axios Example

const axios = require('axios');

const API_URL = 'https://api.explo.co/api/create_customer';
const WAIT_TIME_MS = 60000; // 1 minute

async function createCustomers(customer_post_bodies) {
    for (const customer_post_body of customer_post_bodies) {
        let successful_call = false;
        while (!successful_call) {
            try {
                const response = await axios.post(API_URL, customer_post_body);
                successful_call = true;
            } catch (error) {
                if (error.response && error.response.status === 429) {
                    console.warn('Rate limit exceeded. Waiting for 1 minute.');
                    await new Promise(resolve => setTimeout(resolve, WAIT_TIME_MS));
                } else {
                    console.error(`Error creating customer ${customer.name}:`, error.message);
                    // TODO: Decide how you want to handle other errors.
                }
            }
        }
    }
}

Python, Requests Example

import requests
import time

API_URL = 'https://api.explo.co/api/create_customer'
WAIT_TIME_S = 60  # 1 minute

def create_customers(customer_post_bodies):
    for customer_post_body in customer_post_bodies:
        successful_call = False
        while not successful_call:
            try:
                response = requests.post(API_URL, json=customer_post_body)
                response.raise_for_status()
                successful_call = True
            except requests.exceptions.RequestException as error:
                if response is not None and response.status_code == 429:
                    print('Rate limit exceeded. Waiting for 1 minute.')
                    time.sleep(WAIT_TIME_S)
                else:
                    print(f"Error creating customer {customer_post_body.get('name', 'Unknown')}: {error}")
                    # TODO: Decide how you want to handle other errors.