DEV Community

SEO - NT Tech Innovation
SEO - NT Tech Innovation

Posted on

A Tiny Order Queue for Social Media APIs (So You Stop Getting Rate-Limited)

Anyone who's built on top of social media service APIs knows the pattern. You fire off ten orders, three time out, two come back with "rate limit exceeded" and your customers are refreshing the page wondering what happened.

The fix isn't clever. It's a queue. Here's a minimal one in Python that's good enough for a small reseller tool or a Telegram bot.

The problem

Most SMM-style APIs share a shape: one endpoint, a key, an action (add, status, balance, refill) and form-encoded params. They also share limits. Hammer them and you get throttled, or worse, duplicate orders when you retry a request that actually succeeded.

A tiny queue with idempotency

import time, uuid, sqlite3, requests

API_URL = "https://YOUR-PANEL/api/v2"
API_KEY = "env-var-please"
MIN_GAP = 1.5  # seconds between calls

db = sqlite3.connect("queue.db")
db.execute("""CREATE TABLE IF NOT EXISTS jobs (
  id TEXT PRIMARY KEY, service INT, link TEXT, qty INT,
  status TEXT DEFAULT 'pending', order_id INT, tries INT DEFAULT 0)""")

def enqueue(service, link, qty):
    job_id = str(uuid.uuid4())
    db.execute("INSERT INTO jobs (id, service, link, qty) VALUES (?,?,?,?)",
               (job_id, service, link, qty))
    db.commit()
    return job_id

def worker():
    while True:
        row = db.execute("SELECT id, service, link, qty, tries FROM jobs "
                         "WHERE status='pending' ORDER BY rowid LIMIT 1").fetchone()
        if not row:
            time.sleep(5); continue
        job_id, service, link, qty, tries = row
        try:
            r = requests.post(API_URL, data={"key": API_KEY, "action": "add",
                              "service": service, "link": link, "quantity": qty}, timeout=30)
            data = r.json()
            if "order" in data:
                db.execute("UPDATE jobs SET status='sent', order_id=? WHERE id=?",
                           (data["order"], job_id))
            else:
                db.execute("UPDATE jobs SET status='failed', tries=? WHERE id=?",
                           (tries + 1, job_id))
        except requests.Timeout:
            # don't blindly retry: check status first to avoid duplicates
            db.execute("UPDATE jobs SET status='check', tries=? WHERE id=?",
                       (tries + 1, job_id))
        db.commit()
        time.sleep(MIN_GAP)
Enter fullscreen mode Exit fullscreen mode

The important bits

  • One worker, fixed gap. Simple, predictable, nowhere near any rate limit.
  • Timeouts go to check, not pending. A timeout doesn't mean the order failed. Reconcile against your panel's order history before retrying, or you'll double-charge.
  • SQLite is enough. You don't need Redis for a few hundred orders a day.
  • Keep the key out of the code. Environment variables, always.

Trying it against a real API

If you want something concrete to point this at, BoostingPH is a Philippine panel with the standard v2-style endpoints documented at https://www.boostingph.com/api. And if you're building for Filipino businesses, their social media marketing guide for the Philippines is good background on what your end users are actually trying to achieve.

Queue it. Space it. Reconcile before retrying.

MD Fozla Rabbi, SEO Specialist

Top comments (0)