پرش به محتوا
هوشی

حساب و محدودیت‌ها

خطاها و تلاش مجدد

خطاهای API هوشی همان قالب خطای OpenAI را دارند؛ پس SDKهای رسمی آن‌ها را به exceptionهای آشنا (AuthenticationError، RateLimitError و…) تبدیل می‌کنند.

قالب خطا

JSON
{
  "error": {
    "message": "Model `openai/gpt-9` does not exist or is not available. See GET /v1/models.",
    "type": "invalid_request_error",
    "code": "model_not_found",
    "param": null
  }
}
فیلدتوضیح
messageتوضیح قابل‌خواندن برای انسان (برخی پیام‌ها دوزبانه فارسی/انگلیسی‌اند). برای منطق برنامه به آن تکیه نکن.
typeدستهٔ کلی خطا.
codeکد دقیق و پایدار؛ برای تصمیم‌گیری در کد از این استفاده کن. اگر کد جداگانه‌ای نباشد، برابر type است.
paramفعلاً همیشه null.

جدول کدها

HTTPtypecodeعلتتلاش مجدد؟
400invalid_request_errormodel_requiredفیلد model ارسال نشده.خیر
400invalid_request_errorinvalid_request_errormessages خالی یا نامعتبر است، یا پروایدر درخواست را رد کرده (پیام دقیق در message).خیر
401invalid_api_keyinvalid_api_keyکلید ارسال نشده، با hk- شروع نمی‌شود، حذف/غیرفعال/منقضی شده یا حساب غیرفعال است.خیر
402insufficient_quotainsufficient_quotaموجودی کیف پول API کمتر از حداقل لازم است.بعد از شارژ
402spend_limit_reachedspend_limit_reachedسقف هزینهٔ ماهانهٔ این کلید پر شده.ماه بعد / افزایش سقف
403ip_not_allowedip_not_allowedIP درخواست در فهرست IPهای مجاز کلید نیست.خیر
403permission_errormodel_not_allowedاین کلید اجازهٔ استفاده از این مدل را ندارد.خیر
404invalid_request_errormodel_not_foundمدل وجود ندارد، غیرفعال است یا در API در دسترس نیست (یا نوعش با endpoint نمی‌خواند).خیر
404invalid_request_errorprovider_not_foundپروایدر در API بومی فعال نیست.خیر
404invalid_request_errorendpoint_not_supportedاین مسیر در API بومی پشتیبانی نمی‌شود.خیر
413 / 422invalid_request_errorinvalid_request_errorدرخواست بزرگ‌تر از حد مدل یا نامعتبر از نظر پروایدر.خیر
422——خطای اعتبارسنجی فیلدها در endpointهای تصویر و صدا (قالب {message, errors}).خیر
429rate_limit_exceededrate_limit_exceededسقف درخواست در دقیقهٔ کلید پر شده. هدر Retry-After دارد.بله، بعد از Retry-After
429rate_limit_errorrate_limit_errorپروایدر بالادستی موقتاً محدودیت اعمال کرده (بعد از امتحان همهٔ مسیرها).بله، با backoff
502upstream_errorupstream_errorخطای سمت پروایدر یا پروایدر موقتاً در دسترس نیست.بله، با backoff
503upstream_errorupstream_errorAPI بومی: هیچ مسیر بالادستی سالمی در دسترس نیست.بله، با backoff
504——اتصال به پروایدر برقرار نشد (timeout).بله، با backoff

API بومی

در API بومی، خطاهای هوشی (جدول بالا) با همین قالب برمی‌گردند، ولی خطاهای اعتبارسنجی خود پروایدر (مثلاً 400 از Anthropic) عیناً با قالب همان پروایدر عبور داده می‌شوند. جزئیات در API بومی.

خطا در میانهٔ استریم

وقتی استریم شروع شده باشد (کد 200 ارسال شده)، خطای بعدی پروایدر به‌صورت یک رویداد SSE می‌آید و بلافاصله [DONE] ارسال می‌شود. در این رویداد code کد وضعیت HTTP پروایدر (عدد) است:

Text
data: {"id":"chatcmpl-x","object":"chat.completion.chunk",...,"choices":[{"index":0,"delta":{"content":"بخشی از"},...}]}

data: {"error":{"message":"Overloaded","type":"upstream_error","code":529}}

data: [DONE]

SDKهای رسمی OpenAI این رویداد را به exception تبدیل می‌کنند. اگر خودت SSE را می‌خوانی، هر data را برای کلید error بررسی کن. درخواست‌هایی که با خطا تمام شوند هزینه‌ای ندارند.

راهنمای تلاش مجدد

  • فقط روی 429، 5xx و خطاهای شبکه تلاش مجدد کن؛ 4xxهای دیگر با تکرار درست نمی‌شوند.
  • در 429 با کد rate_limit_exceeded، به اندازهٔ هدر Retry-After (ثانیه) صبر کن.
  • در بقیهٔ موارد از exponential backoff با jitter استفاده کن (مثلاً ۱، ۲، ۴، ۸ ثانیه + عدد تصادفی) و حداکثر ۴–۵ بار.
  • برای پایداری بیشتر، بعد از چند شکست به یک مدل جایگزین از پروایدر دیگر سوییچ کن (نمونهٔ fallback).
  • شناسهٔ X-Request-Id پاسخ را لاگ کن تا پشتیبانی بتواند درخواست را پیدا کند.

نمونه کد

from openai import OpenAI

# SDK رسمی خودش روی 408/409/429/5xx با backoff تلاش مجدد می‌کند
client = OpenAI(base_url="https://api.hooshi.ai/v1", api_key="hk-...", max_retries=4, timeout=120)

import openai
try:
    r = client.chat.completions.create(model="openai/gpt-5.5", messages=[{"role": "user", "content": "سلام"}])
except openai.AuthenticationError:
    ...  # 401: کلید را بررسی کن
except openai.PermissionDeniedError as e:
    ...  # 403: ip_not_allowed یا model_not_allowed
except openai.APIStatusError as e:
    if e.status_code == 402:
        code = e.body.get("code") if isinstance(e.body, dict) else None
        ...  # insufficient_quota یا spend_limit_reached → هشدار به تیم
    else:
        raise