Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kameleoon.com/llms.txt

Use this file to discover all available pages before exploring further.

This guide explains how to delete multiple accounts using the Automation API while complying with API rate limits. It uses the Delete account endpoint.

Prerequisites

Before using the Automation API, you must obtain an access token. For instructions, see the Authentication guide.
Include your token in the Authorization header of every request:
Authorization: Bearer YOUR_ACCESS_TOKEN

Handle rate limits

The Automation API enforces two rate-limiting windows to control request traffic:
Time windowMaximum requests
10 seconds50 requests
1 hour1,000 requests
If you send requests too quickly, the API returns an HTTP 429 Too Many Requests status code.
To avoid these limits, process your requests in controlled batches:
  • Send a maximum of 50 requests every 10 seconds.
  • Send a maximum of 1,000 requests per hour.

Example: Deleting 230 accounts

To delete 230 accounts, divide your requests into the following batches:
BatchRequestsWait time
150Wait 10 seconds
250Wait 10 seconds
350Wait 10 seconds
450Wait 10 seconds
530Complete

Delete accounts using Python

Use the following Python script to send delete requests sequentially and manage rate limits automatically:
delete_accounts.py
import time
import requests

API_URL = "https://api.kameleoon.com/accounts/"
ACCESS_TOKEN = "YOUR_ACCESS_TOKEN"

ACCOUNT_IDS = [12345, 54321]

MAX_PER_10_SECONDS = 50
MAX_PER_HOUR = 1000

TEN_SECONDS = 10
ONE_HOUR = 3600


def delete_account(session, account_id):
    headers = {
        "Authorization": f"Bearer {ACCESS_TOKEN}",
    }

    url = f"{API_URL}{account_id}"

    try:
        response = session.delete(url, headers=headers)

        if response.status_code == 429:
            return "rate_limited", None

        if response.status_code in (200, 204):
            return True, response.json() if response.content else {}

        return False, response.text

    except requests.exceptions.RequestException as e:
        return False, str(e)


def process_accounts(account_ids):

    session = requests.Session()

    start_hour = time.monotonic()
    hour_count = 0

    for i in range(0, len(account_ids), MAX_PER_10_SECONDS):

        batch = account_ids[i:i + MAX_PER_10_SECONDS]

        # Enforce hourly limit BEFORE sending requests
        if hour_count + len(batch) > MAX_PER_HOUR:
            elapsed = time.monotonic() - start_hour
            sleep_time = max(0, ONE_HOUR - elapsed)

            print(f"Hourly limit reached. Sleeping {sleep_time:.2f} seconds")
            time.sleep(sleep_time)

            start_hour = time.monotonic()
            hour_count = 0

        batch_start = time.monotonic()

        for account_id in batch:

            while True:
                # Check hourly limit before EACH request
                if hour_count >= MAX_PER_HOUR:
                    elapsed = time.monotonic() - start_hour
                    sleep_time = max(0, ONE_HOUR - elapsed)

                    print(f"Hourly limit reached. Sleeping {sleep_time:.2f} seconds")
                    time.sleep(sleep_time)

                    start_hour = time.monotonic()
                    hour_count = 0

                result, data = delete_account(session, account_id)

                # Count every attempt as a request
                hour_count += 1

                if result == True:
                    print(f"Account {account_id} deleted")
                    break

                elif result == "rate_limited":
                    elapsed = time.monotonic() - start_hour

                    # If close to hourly limit, wait for full reset
                    if hour_count >= MAX_PER_HOUR or elapsed >= ONE_HOUR:
                        sleep_time = max(0, ONE_HOUR - elapsed)
                        print(f"429 likely due to hourly limit. Sleeping {sleep_time:.2f} seconds")
                        time.sleep(sleep_time)

                        start_hour = time.monotonic()
                        hour_count = 0
                    else:
                        print("429 received. Waiting 10 seconds...")
                        time.sleep(TEN_SECONDS)

                    continue

                else:
                    print(f"Failed to delete {account_id}: {data}")
                    break

        # Enforce 10-second window
        elapsed = time.monotonic() - batch_start

        if elapsed < TEN_SECONDS:
            sleep_time = TEN_SECONDS - elapsed
            print(f"Waiting {sleep_time:.2f} seconds before next batch")
            time.sleep(sleep_time)


def main():
    process_accounts(ACCOUNT_IDS)


if __name__ == "__main__":
    main()
The script manages account deletion while complying with Automation API rate limits by:
  • Sending requests sequentially.
  • Processing accounts in batches of 50.
  • Waiting between batches to enforce the 10-second limit.
  • Pausing if the process reaches the hourly limit of 1,000 requests.
This approach prevents rate-limit errors and ensures reliable account deletion during large cleanup or offboarding operations.