رفتن به محتوا

خطاهای API هوش مصنوعی؛ معنی ۴۰۱، ۴۰۲، ۴۲۹ و ۵۰۰ و راه‌حل هر کدام

هر کد خطای API هیبانا یعنی چه و چه باید کرد؛ از ۴۰۱ و ۴۰۲ تا ۴۲۹ و ۵۰۰، با کد پایتون آزموده‌شده برای مدیریت خطا، تلاش مجدد و بررسی موجودی.

تیم هیبانا۶ دقیقه مطالعه
رباتی کوچک پشت میز کار با ذره‌بین ردیفی از چرخ‌دنده‌ها را بررسی می‌کند و کنارش جعبه‌ابزار و ساعت شنی قرار دارد

برنامه‌ای که به API هوش مصنوعی وصل است دیر یا زود با خطا روبه‌رو می‌شود: کلید اشتباه کپی شده، موجودی تمام شده یا درخواست‌ها پشت سر هم زیاد شده‌اند. خبر خوب این است که هر خطا یک کد وضعیت HTTP و یک شناسهٔ مشخص دارد و از روی همین دو می‌شود فهمید مشکل از کجاست و آیا تلاش دوباره فایده دارد یا نه. در این مطلب کدهای ۴۰۰، ۴۰۱، ۴۰۲، ۴۰۳، ۴۲۹ و ۵۰۰ را همان‌طور که API هیبانا برمی‌گرداند مرور می‌کنیم و برای هر کدام راه‌حل می‌گوییم. همهٔ کدهای پایتون این مطلب را روی API واقعی اجرا کرده‌ایم و خروجی‌ها واقعی‌اند.

شکل یک پاسخ خطا

هیبانا سازگار با OpenAI است و خطاها را هم با همان قالب برمی‌گرداند. مثلاً اگر کلید API اشتباه باشد، پاسخ با کد وضعیت ۴۰۱ و این بدنه برمی‌گردد:

{"error":{"message":"Invalid API key provided. Pass your key as 'Authorization: Bearer <key>' or 'X-Api-Key: <key>'.","type":"authentication_error","code":"invalid_api_key","param":null}}

سه فیلد مهم‌اند:

  • code: شناسهٔ پایدار خطا. برنامهٔ شما باید روی همین تصمیم بگیرد.
  • message: توضیحی برای خواندن انسان که ممکن است در آینده تغییر کند؛ برای تصمیم‌گیری خودکار به آن تکیه نکنید.
  • param: اگر خطا به یک فیلد مشخص مربوط باشد، نام همان فیلد (مثلاً model).

فهرست کامل کدها در مدیریت خطاها آمده است. اینجا سراغ پرتکرارترین‌ها می‌رویم.

۴۰۱؛ کلید API پذیرفته نشد

خطای ۴۰۱ یعنی سرور نتوانسته شما را شناسایی کند. سه علت رایج دارد:

  • کلید اشتباه یا ناقص کپی شده، یا کلید را از داشبورد حذف کرده‌اید؛
  • کلمهٔ Bearer در هدر Authorization جا افتاده است؛
  • مقدار هدر داخل علامت نقل‌قول گذاشته شده و نقل‌قول هم جزو کلید خوانده می‌شود.

شکل درست هدر Authorization: Bearer YOUR_API_KEY است. اگر از SDK رسمی openai استفاده می‌کنید، این هدر را خود کتابخانه می‌سازد و فقط باید کلید درست را به api_key بدهید. تلاش دوباره برای ۴۰۱ بی‌فایده است؛ تا کلید را درست نکنید، همان پاسخ برمی‌گردد. جزئیات بیشتر در احراز هویت آمده و اگر کلید را گم کرده‌اید، از دریافت کلید API یک کلید تازه بسازید.

۴۰۲؛ موجودی یا سقف بودجه

کد ۴۰۲ در هیبانا دو حالت دارد که با فیلد code از هم جدا می‌شوند:

codeیعنی چهچه کار کنید
insufficient_fundsموجودی کیف پول برای این درخواست کافی نیستکیف پول را شارژ کنید یا مدل ارزان‌تری انتخاب کنید
budget_exceededسقف بودجهٔ ماهانهٔ همین کلید API پر شده استسقف بودجهٔ کلید را از داشبورد سازمان بالا ببرید یا تا ماه بعد صبر کنید

حالت دوم مخصوص کلیدهای سازمانی است که برایشان سقف بودجهٔ ماهانه تعیین شده است. ممکن است کیف پول سازمان موجودی داشته باشد، اما همین یک کلید به سقف خودش رسیده باشد. پس اگر کیف پول خالی نیست و باز هم ۴۰۲ می‌گیرید، اول code را نگاه کنید.

بهتر است اصلاً به ۴۰۲ نرسید. موجودی کیف پول را می‌توانید با GET /v1/user/balance از داخل برنامه بخوانید و پیش از تمام شدنش هشدار بدهید:

import osimport requests def get_balance():    r = requests.get(        "https://api-ai.hibanacloud.ir/v1/user/balance",        headers={"Authorization": f"Bearer {os.environ['HIBANA_API_KEY']}"},        timeout=10,    )    r.raise_for_status()    return r.json()  # {"object": "user.balance", "balance": ..., "currency": "IRR"} data = get_balance()MIN_RIAL = 500_000  # آستانهٔ هشدار خودتانif data["balance"] < MIN_RIAL:    print("موجودی کم است؛ پیش از خطای 402 کیف پول را شارژ کنید")else:    print("موجودی کافی است، واحد:", data["currency"])

خروجی واقعی:

موجودی کافی است، واحد: IRR

موجودی به ریال برگردانده می‌شود. این endpoint موجودی کیف پول را می‌دهد، نه سقف بودجهٔ یک کلید. توضیح کامل در بررسی موجودی کاربر است و برای کم کردن مصرف، توکن چیست و هزینهٔ API چطور حساب می‌شود را بخوانید.

۴۰۰ و ۴۰۳؛ ایراد در درخواست یا دسترسی

کد ۴۰۰ یعنی خود درخواست ایراد دارد و تا آن را عوض نکنید، همان خطا برمی‌گردد. رایج‌ترین مورد، نام اشتباه مدل است:

{"error":{"message":"The requested model 'gpt-unknown' was not found or is disabled.","type":"invalid_request_error","param":"model","code":"model_not_found"}}

نام دقیق هر مدل را از لیست مدل‌ها بردارید؛ نام مدل باید دقیقاً همان رشته‌ای باشد که در فهرست آمده است. پیوست‌ها (تصویر، PDF، صوت و ویدیو) هم کدهای ۴۰۰ مخصوص خود را دارند، مثل image_too_large یا document_input_not_supported، که جدولشان در مستندات خطاها آمده است.

کد ۴۰۳ یعنی شما شناسایی شده‌اید، اما اجازهٔ این کار را ندارید. مثلاً در کلیدهای سازمانی می‌شود مدل‌های مجاز هر کلید را محدود کرد؛ درخواست با چنین کلیدی به مدلی خارج از فهرست مجاز، ۴۰۳ با کد model_not_allowed می‌گیرد. اگر دلیل ۴۰۳ را نمی‌دانید، از داشبورد تیکت پشتیبانی ثبت کنید.

۴۲۹؛ درخواست‌ها از سقف نرخ گذشته‌اند

هر حساب در هر پنجرهٔ زمانی سقفی برای تعداد درخواست دارد. این سقف برای هر کاربر و هر مدل جدا حساب می‌شود و به سطح حساب بستگی دارد. سرور در هر پاسخ موفق هم وضعیت فعلی را در هدرها می‌فرستد و با SDK openai می‌شود آن‌ها را خواند:

import osfrom openai import OpenAI client = OpenAI(    api_key=os.environ["HIBANA_API_KEY"],    base_url="https://api-ai.hibanacloud.ir/v1",) raw = client.chat.completions.with_raw_response.create(    model="gpt-5-nano",    messages=[{"role": "user", "content": "فقط بنویس: سلام"}],)print("Limit:", raw.headers.get("x-ratelimit-limit"))print("Remaining:", raw.headers.get("x-ratelimit-remaining"))print("Window:", raw.headers.get("x-ratelimit-window-seconds"))completion = raw.parse()print("پاسخ:", completion.choices[0].message.content)

خروجی واقعی برای حساب ما (عددهای حساب شما بسته به سطح آن فرق می‌کنند):

Limit: 500Remaining: 498Window: 60پاسخ: سلام

وقتی Remaining به صفر برسد، درخواست بعدی ۴۲۹ با کد rate_limited می‌گیرد و هدر Retry-After می‌گوید چند ثانیه صبر کنید. برخلاف ۴۰۱ و ۴۰۲، اینجا تلاش دوباره کار درستی است، به شرطی که با فاصله باشد. نکتهٔ مهم: طبق مستندات محدودیت نرخ، نقض مکرر محدودیت ممکن است به مسدود شدن موقت یا دائمی منجر شود؛ پس حلقه‌ای که بی‌وقفه دوباره می‌فرستد مشکل را بدتر می‌کند.

۵۰۰؛ خطای سمت سرور

کدهای ۵۰۰ به بالا یعنی درخواست شما ایرادی ندارد و مشکل سمت سرور یا ارائه‌دهندهٔ مدل است. راه‌حل همان تلاش دوباره با فاصلهٔ فزاینده (exponential backoff) است: یک ثانیه، بعد دو ثانیه، بعد چهار ثانیه و به همین ترتیب. اگر خطا ادامه داشت، چند دقیقه بعد دوباره امتحان کنید و در صورت نیاز تیکت ثبت کنید.

مدیریت همهٔ خطاها در پایتون

کتابخانهٔ رسمی openai برای هر کد وضعیت یک کلاس خطا دارد. طبق مستندات این کتابخانه، ۴۰۰ به BadRequestError، ۴۰۱ به AuthenticationError، ۴۰۳ به PermissionDeniedError، ۴۲۹ به RateLimitError و ۵۰۰ به بالا به InternalServerError تبدیل می‌شود و همه از APIStatusError ارث می‌برند. ۴۰۲ کلاس جداگانه‌ای ندارد و باید آن را از status_code تشخیص داد.

همین مستندات می‌گوید SDK خطاهای اتصال، ۴۰۸، ۴۰۹، ۴۲۹ و ۵۰۰ به بالا را به‌طور پیش‌فرض دو بار با backoff کوتاه دوباره امتحان می‌کند و تعداد آن با max_retries تنظیم می‌شود. یعنی برای ۴۲۹ و ۵۰۰ لازم نیست حلقهٔ تلاش مجدد را خودتان بنویسید:

import osimport sysimport openaifrom openai import OpenAI client = OpenAI(    api_key=os.environ["HIBANA_API_KEY"],    base_url="https://api-ai.hibanacloud.ir/v1",    max_retries=3,  # برای 429 و 5xx خودِ SDK دوباره تلاش می‌کند) def ask(model, text):    try:        r = client.chat.completions.create(            model=model,            messages=[{"role": "user", "content": text}],        )        return r.choices[0].message.content    except openai.AuthenticationError as e:      # 401        print("401:", e.body.get("code"), "→ کلید یا هدر Authorization را بررسی کنید")    except openai.PermissionDeniedError as e:    # 403        print("403:", e.body.get("code"), "→ این کلید اجازهٔ این کار را ندارد")    except openai.RateLimitError as e:           # 429، پس از تمام شدن تلاش‌های مجدد        print("429:", e.response.headers.get("Retry-After"), "ثانیه صبر کنید")    except openai.BadRequestError as e:          # 400        print("400:", e.body.get("code"), "→", e.body.get("message"))    except openai.APIStatusError as e:           # بقیه، از جمله 402 و 5xx        if e.status_code == 402:            print("402:", e.body.get("code"), "→ موجودی یا سقف بودجهٔ کلید")        else:            print(e.status_code, "→ خطای سرور؛ بعداً دوباره امتحان کنید")    except openai.APIConnectionError:        print("اتصال برقرار نشد؛ شبکه یا timeout") model = sys.argv[1] if len(sys.argv) > 1 else "gpt-5-nano"answer = ask(model, "فقط بنویس: سلام")if answer:    print("پاسخ:", answer)

این اسکریپت را سه بار اجرا کردیم: یک بار عادی، یک بار با نام مدلی که وجود ندارد (python errors.py gpt-unknown) و یک بار با کلید غلط در متغیر محیطی HIBANA_API_KEY. خروجی واقعی به همان ترتیب:

پاسخ: سلام400: model_not_found → The requested model 'gpt-unknown' was not found or is disabled.401: invalid_api_key → کلید یا هدر Authorization را بررسی کنید

ترتیب exceptها مهم است: کلاس‌های خاص باید پیش از APIStatusError بیایند، وگرنه هیچ‌وقت به آن‌ها نمی‌رسید.

تلاش مجدد بدون هزینهٔ دوباره

اگر پاسخ در راه برگشت گم شود، تلاش دوباره ممکن است یک بار دیگر هزینه کسر کند. برای جلوگیری، هدر Idempotency-Key را با یک شناسهٔ یکتا بفرستید؛ با SDK کافی است extra_headers={"Idempotency-Key": key} را به درخواست اضافه کنید. ما همین کار را دو بار با یک کلید امتحان کردیم و پاسخ دوم هدر Idempotent-Replayed: true داشت، یعنی مدل دوباره صدا زده نشد. جزئیات در کلید یکتاسازی آمده است.

خلاصهٔ تصمیم‌گیری

کدتلاش دوباره؟اولین قدم
۴۰۰نهcode و param را بخوانید و درخواست را درست کنید
۴۰۱نهکلید و هدر Authorization را بررسی کنید
۴۰۲نهinsufficient_funds یا budget_exceeded؟ شارژ یا افزایش سقف
۴۰۳نهدسترسی کلید را بررسی کنید یا تیکت ثبت کنید
۴۲۹بله، پس از Retry-Afterسرعت ارسال را کم کنید
۵۰۰ به بالابله، با فاصلهٔ فزایندهاگر ادامه داشت، تیکت ثبت کنید

جمع‌بندی

برای مدیریت خطا، به کد وضعیت و فیلد code نگاه کنید، نه به متن پیام. ۴۰۰ تا ۴۰۳ با تلاش دوباره درست نمی‌شوند و چیزی باید عوض شود؛ ۴۲۹ و ۵۰۰ با صبر و تلاش دوباره برطرف می‌شوند و SDK رسمی openai بخش زیادی از این کار را خودش انجام می‌دهد. اگر خطا کد ندارد و فقط نشانه‌ای می‌بینید، مثل درخواستی که معلق می‌ماند، از حل مشکلات شروع کنید. برای شروع از صفر هم راهنمای API هوش مصنوعی را ببینید.

مطالب مرتبط

با یک کلید به همه مدل‌ها وصل شوید

GPT، Claude، Gemini و ده‌ها مدل دیگر، با پرداخت ریالی و یک API سازگار با OpenAI.