AIWave API

Rate Limits

Rate limiting protects both the gateway and the upstream providers behind it. When you exceed a limit the AIWave API returns 429 Too Many Requests. This page explains how to detect it, how to back off correctly, and how to structure a workload so you rarely hit the ceiling at all.

Recognising a rate limit

A 429 carries the standard error envelope:

{
  "error": {
    "message": "Rate limit exceeded",
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded"
  }
}

A 429 can also mean the account balance is exhausted rather than a request-rate problem. Check the console before assuming it is throughput.

Exponential backoff with jitter

Retrying immediately makes congestion worse. Back off exponentially and add jitter so that many clients do not retry in lockstep.

import time, random
from openai import OpenAI, APIStatusError

client = OpenAI(api_key="sk-YOUR_KEY", base_url="https://aiwave.live/v1")

def with_backoff(fn, attempts=6, base=1.0, cap=32.0):
    for i in range(attempts):
        try:
            return fn()
        except APIStatusError as e:
            if e.status_code != 429 or i == attempts - 1:
                raise
            delay = min(cap, base * (2 ** i)) * (0.5 + random.random())
            time.sleep(delay)

resp = with_backoff(lambda: client.chat.completions.create(
    model="deepseek-v4-flash",
    messages=[{"role": "user", "content": "Hello"}],
))

Bounding concurrency

Most rate-limit problems are really concurrency problems. A semaphore around your worker pool is usually more effective than any retry strategy.

import asyncio
from openai import AsyncOpenAI

client = AsyncOpenAI(api_key="sk-YOUR_KEY", base_url="https://aiwave.live/v1")
sem = asyncio.Semaphore(8)          # tune to your workload

async def ask(prompt):
    async with sem:
        r = await client.chat.completions.create(
            model="deepseek-v4-flash",
            messages=[{"role": "user", "content": prompt}],
        )
        return r.choices[0].message.content

async def main(prompts):
    return await asyncio.gather(*(ask(p) for p in prompts))

Reducing the requests you need

Related failure modes

A 503 is not a rate limit — it means the upstream provider is overloaded, and the right response is a fallback model rather than a longer sleep. See error codes for the full decision table.

Related documentation

Get an API key →All docs →