محدودیت نرخ (Rate limits)

سقف درخواست در دقیقهٔ هر کلید، هدرهای X-RateLimit و Retry-After، سقف استریم هم‌زمان، سهم روزانهٔ مدل‌های رایگان و سقف ماهانهٔ کلید، با کد تلاش دوباره.

به‌روزرسانی: ۱ مهر ۱۴۰۵

چهار محدودیت مستقل روی درخواست‌ها اعمال می‌شود. سه‌تای اول را خودت در داشبورد تنظیم می‌کنی یا از پیش‌فرض استفاده می‌کنی؛ چهارمی مربوط به مدل‌های رایگان است. همه با 429 و یک code مشخص برمی‌گردند تا در کد قابل تفکیک باشند.

درخواست در دقیقه (هر کلید)

هر کلید یک rate_limit_rpm دارد، پیش‌فرض ۶۰ و قابل تنظیم بین ۱ تا ۶۰۰ در داشبورد ← کلیدها. پنجره لغزان است، نه دقیقهٔ تقویمی. همهٔ مسیرهای پولی (chat/completions، completions، embeddings) در همین شمارنده‌اند؛ GET /v1/models و GET /v1/uttapen/* شمرده نمی‌شوند.

روی هر پاسخ این هدرها هست:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1788734238

X-RateLimit-Reset زمان Unix (ثانیه) است که پنجره خالی می‌شود. وقتی سقف پر شد:

HTTP/1.1 429 Too Many Requests
Retry-After: 19
X-RateLimit-Remaining: 0

{"error":{"message":"سقف 60 درخواست در دقیقه برای این کلید پر شده است.","type":"rate_limit_exceeded","code":"rate_limit_exceeded","param":null}}

اگر بیشتر لازم داری، عدد را روی خود کلید بالا ببر؛ نیازی به تماس با ما نیست. برای بارهای موازی سنگین (batch پردازش اسناد)، چند کلید با نام جدا بساز تا هم شمارنده جدا باشد هم گزارش مصرف تفکیک شود.

استریم هم‌زمان (هر کاربر)

هر کاربر حداکثر ۱۰ استریم باز هم‌زمان دارد، مستقل از تعداد کلیدها. درخواست یازدهم 429 too_many_concurrent_streams با Retry-After: 5 می‌گیرد. شمارنده با پایان یا قطع استریم فوراً آزاد می‌شود. درخواست‌های embeddings هم در همین شمارنده‌اند (پاسخ یک دستهٔ بزرگ بردار تا خوانده‌شدن کامل جا نگه می‌دارد)؛ بقیهٔ درخواست‌های غیراستریم در آن نیستند و فقط با RPM محدودند.

سقف ماهانهٔ کلید

اگر monthly_limit_toman روی کلید ست باشد، مجموع هزینهٔ درخواست‌های تسویه‌شدهٔ آن کلید در ماه جلالی جاری به‌علاوهٔ رزروهای باز با سقف مقایسه می‌شود. عبور از آن 429 key_monthly_limit_reached با بلوک uttapen شامل monthly_limit_toman و spent_toman می‌دهد. این چک داخل همان تراکنش رزرو انجام می‌شود، پس دو درخواست موازی نمی‌توانند با هم از سقف رد شوند. اول ماه جلالی شمارنده صفر می‌شود.

مدل‌های رایگان

مدل‌های با پسوند :free بدون شارژ کار می‌کنند ولی دو سقف دارند:

  1. سهم روزانهٔ هر کاربر: پیش‌فرض ۵۰ درخواست در روز روی مجموع مدل‌های رایگان. عبور → 429 free_quota_exceeded با Retry-After: 3600 و در بلوک uttapen، alternative_model و قیمت تقریبی‌اش. درخواست‌هایی که سازندهٔ مدل سرویس نداده (خطای قبل از اولین بایت) به سهم برمی‌گردند.
  2. ظرفیت مشترک سازندهٔ مدل: ظرفیت رایگان بین همهٔ کاربران یوتاپن مشترک است. وقتی سازندهٔ مدل 429 بدهد، تو 429 free_capacity_exhausted با Retry-After می‌گیری. این حالت را کنترل نمی‌کنیم؛ در ساعت‌های شلوغ عادی است.

۳. سقف خروجی هر درخواست: اگر max_tokens ندهی، سقف پیش‌فرض ۳۲٬۷۶۸ توکن اعمال می‌شود — چند مدل رایگان سقف خیلی بزرگ‌تری دارند، پس اگر خروجی بلندتری می‌خواهی خودت max_tokens را بنویس.

مدل‌های رایگان برای تست و نمونه‌سازی‌اند. برای هر چیزی که کاربر واقعی منتظرش است، مدل پولی ارزان (مثل openai/gpt-5-nano یا google/gemini-2.5-flash-lite) قابل‌اعتمادتر است.

محدودیت سمت سازندهٔ مدل

گاهی خود سازندهٔ مدل یک مدل را محدود می‌کند. در این حالت 429 upstream_rate_limited می‌گیری. اگر سه بار پشت سر هم برای یک مدل اتفاق بیفتد، یوتاپن آن مدل را چند ده ثانیه «سرد» علامت می‌زند و بدون رفتن به سازندهٔ مدل 429 با Retry-After می‌دهد تا وقتت هدر نرود. مدل هم‌رده از سازندهٔ دیگر (مثلاً google/gemini-2.5-flash به‌جای openai/gpt-5-mini) معمولاً همان لحظه در دسترس است؛ فیلد models برای جایگزینی خودکار همین کار را می‌کند (migration).

تکرار درست، با فاصلهٔ فزاینده

import random, time
import openai

def create_with_retry(**kwargs):
    for attempt in range(4):
        try:
            return client.chat.completions.create(**kwargs)
        except openai.RateLimitError as e:
            code = e.code
            if code in ("key_monthly_limit_reached", "free_quota_exceeded"):
                raise  # صبر کردن فایده ندارد
            retry_after = e.response.headers.get("retry-after")
            wait = float(retry_after) if retry_after else min(2 ** attempt, 20)
            time.sleep(wait + random.random())
        except openai.InternalServerError:
            time.sleep(min(2 ** attempt, 20) + random.random())
    raise RuntimeError("uttapen: too many retries")

نکته‌ها:

  • Retry-After را جدی بگیر؛ زودتر زدن فقط شمارنده را پر نگه می‌دارد.
  • کدهای key_monthly_limit_reached و free_quota_exceeded با صبر حل نمی‌شوند؛ آن‌ها را از حلقهٔ تکرار بیرون بگذار.
  • SDK رسمی خودش دو بار تکرار می‌کند (max_retries). اگر لایهٔ تکرار خودت را داری، max_retries=0 بگذار تا تکرارها چند برابر نشوند.
  • برای بار زیاد، یک صف (Redis، RabbitMQ) با نرخ کمی کمتر از rate_limit_rpm ثابت‌تر از تکرار واکنشی است.

پیش‌فرض‌ها در یک نگاه

محدودیتمقدارcode
درخواست در دقیقه، هر کلید۶۰ (۱ تا ۶۰۰)rate_limit_exceeded
استریم هم‌زمان، هر کاربر۱۰too_many_concurrent_streams
سقف ماهانه، هر کلیدبدون سقف مگر تنظیم کنیkey_monthly_limit_reached
مدل رایگان، هر کاربر۵۰ درخواست در روزfree_quota_exceeded
ظرفیت رایگان سازندهٔ مدلمشترکfree_capacity_exhausted
بدنهٔ درخواست۲۰ مگابایتrequest_too_large (413)
هنوز کلید API نداری؟

با شماره موبایل ثبت‌نام کن، کیف پول را از ۱۰۰٬۰۰۰ تومان شارژ کن و کلید بساز. مدل‌های رایگان بدون شارژ هم کار می‌کنند — تا ۵۰ درخواست در روز. ساخت کلید API ←