# معرفی > API فارسی دانا برای ترجمه، تصمیم و گفت‌وگو، با یک کلید و یک آدرس URL: https://dana.expert/docs دانا API هوش مصنوعی فارسی است. سه کار را از راه API انجام می‌دهد: ترجمهٔ انگلیسی به فارسی با **هدهد**، تصمیم‌های بسته روی متن فارسی با **سنجه** و گفت‌وگو به فارسی با **هما**. - **هدهد** (مترجم انگلیسی به فارسی): متن عادی، فنی یا Markdown؛ لحن رسمی یا خودمانی. [راهنما](https://dana.expert/docs/translate)، [مرجع API](https://dana.expert/docs/api-reference/translate) - **سنجه** (مدل‌های تصمیم، سیستم ۱): قناری، کبوتر، شاهین (به‌زودی). [راهنما](https://dana.expert/docs/decide)، [مرجع API](https://dana.expert/docs/api-reference/decide) - **هما** (مدل‌های زبانی فارسی): برای گفت‌وگو و پاسخ به پرسش، با رابط‌های سازگار با OpenAI و Anthropic. [راهنما](https://dana.expert/docs/homa)، [مرجع API](https://dana.expert/docs/api-reference/chat-completions) برای نخستین درخواست، [شروع سریع](https://dana.expert/docs/quickstart) را ببینید: کلید بسازید و در سه قدم نخستین ترجمه را بگیرید. ## آدرس پایه ``` https://api.dana.expert/v1 ``` یک کلید برای همهٔ مسیرها کافی است. کلید را از [کنسول دانا](https://console.dana.expert/keys) بسازید و در هدر `Authorization: Bearer ...` بفرستید ([حساب و کلید API](https://dana.expert/docs/authentication)). ## امروز چه در دسترس است | سرویس | مسیر | شناسهٔ مدل | وضعیت | |---|---|---|---| | هدهد، مترجم | `POST /v1/translate` | `dana-translator` (نسخهٔ `hodhod-v2.3`) | در دسترس | | سنجه: قناری و کبوتر | `POST /v1/decide` | `ghanari` و `kabootar` | در دسترس | | هما، گفت‌وگو | `POST /v1/chat/completions` و `POST /v1/messages` | `homa` | در دسترس | نسخهٔ مدلی که جواب داده در فیلد `model_version` هر پاسخ می‌آید؛ جدول کامل در [مدل‌ها](https://dana.expert/docs/models) است. ## از کجا شروع کنم - تازه‌کارید؟ [شروع سریع](https://dana.expert/docs/quickstart) در سه قدم به نخستین ترجمه می‌رساندتان. - دنبال فیلدهای دقیق یک مسیرید؟ [مرجع API](https://dana.expert/docs/api-reference) هر مسیر را با بدنهٔ درخواست، پاسخ و خطاها دارد. - خطا گرفته‌اید؟ [خطاها](https://dana.expert/docs/errors) هر کد را با علت و راه‌حلش دارد. - `429` می‌گیرید؟ [محدودیت‌ها](https://dana.expert/docs/rate-limits) علت‌ها را از هم جدا می‌کند. ## برای ابزارهای هوش مصنوعی هر صفحه نسخهٔ Markdown دارد. دکمهٔ «کپی صفحه» بالای هر صفحه متن آن را کپی می‌کند و از منوی کنارش می‌شود همان صفحه یا همهٔ مستندات را در یک فایل `.md` گرفت. فهرست صفحه‌ها در [`/llms.txt`](https://dana.expert/llms.txt) و متن کامل در [`/llms-full.txt`](https://dana.expert/llms-full.txt) است. --- # شروع سریع > نخستین درخواست به هدهد و سنجه با نمونه‌های curl، Python و Node.js URL: https://dana.expert/docs/quickstart سه قدم تا نخستین پاسخ: کلید بسازید، در متغیر محیطی بگذارید، یک متن انگلیسی برای ترجمه بفرستید. بعد همان کلید را روی سنجه امتحان کنید. ## ۱. کلید API بسازید در [کنسول دانا](https://console.dana.expert/keys) روی ساخت کلید بزنید و نامی بگذارید که بشناسیدش. کلید با `dn-live-` شروع می‌شود و **فقط همان یک بار** کامل نشان داده می‌شود، پس همان‌جا کپی کنید. ## ۲. کلید را در محیط بگذارید ```bash export DANA_API_KEY="dn-live-..." ``` ## ۳. یک متن ترجمه کنید **curl:** ```bash curl https://api.dana.expert/v1/translate \ -H "Authorization: Bearer $DANA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"text": "The meeting moved to Tuesday."}' ``` **Python:** ```python import os import requests r = requests.post( "https://api.dana.expert/v1/translate", headers={"Authorization": f"Bearer {os.environ['DANA_API_KEY']}"}, json={"text": "The meeting moved to Tuesday."}, timeout=60, ) r.raise_for_status() print(r.json()["text"]) ``` **Node.js:** ```js const r = await fetch("https://api.dana.expert/v1/translate", { method: "POST", headers: { Authorization: `Bearer ${process.env.DANA_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ text: "The meeting moved to Tuesday." }), }); console.log((await r.json()).text); ``` ## پاسخ موفق ```json { "text": "جلسه به روز سه‌شنبه موکول شد.", "register": "formal", "model": "dana-translator", "model_version": "hodhod-v2.3", "fallback": false, "usage": {"prompt_tokens": 6, "completion_tokens": 22, "total_tokens": 28} } ``` `model_version` نسخهٔ مترجمی است که جواب داده: هدهد v2.3. جزئیات لحن و فیلدها در [مترجم](https://dana.expert/docs/translate) است. ## بعد از ترجمه، سنجه را امتحان کنید همان کلید روی `POST /v1/decide` هم کار می‌کند. یک متن و یک پرسش بله یا خیر بفرستید: ```bash curl https://api.dana.expert/v1/decide \ -H "Authorization: Bearer $DANA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "state": "سه روز است سفارشم را پرداخت کرده‌ام ولی هنوز ارسال نشده.", "questions": {"complaint": {"type": "noul", "instructions": "آیا این پیام شکایت است؟"}} }' ``` جواب احتمال «بله» را می‌دهد، مثلا `"noul": 0.9521`، همراه `"model": "ghanari"` و `"model_version": "ghanari-ir-v0.1"`. سه نوع پرسش و مدل کبوتر در [سنجه](https://dana.expert/docs/decide) آمده است. ## اگر جواب نگرفتید | کدی که دیدید | معنایش | کار بعدی | |---|---|---| | `401` | کلید نرسید یا شناخته نشد | ببینید `$DANA_API_KEY` واقعا مقدار دارد و فاصلهٔ اضافه ندارد | | `400` | بدنهٔ درخواست درست نیست | متن پیام خطا می‌گوید کدام فیلد | | `429` | نرخ، ظرفیت، سقف توکن یا اعتبار | فیلد `type` را بخوانید؛ چهار علت جدا دارد | | `503` با `code` برابر `model_unavailable` | مدل همین حالا در دسترس نیست | چند دقیقه بعد دوباره بفرستید | فهرست کامل کدها و راه‌حل هرکدام در [خطاها](https://dana.expert/docs/errors) آمده است. هدر درست `Authorization: Bearer ` است؛ کلید بدون `Bearer` همان `401` را می‌دهد. ## گفت‌وگو با هما همان کلید روی هما هم کار می‌کند: `"model": "homa"` را به `POST /v1/chat/completions` یا `POST /v1/messages` بفرستید. نمونه و محدودیت‌ها در [هما](https://dana.expert/docs/homa) آمده است. ## قدم بعدی - [مترجم](https://dana.expert/docs/translate): لحن، فیلدهای پاسخ و هزینه - [سنجه](https://dana.expert/docs/decide): سه نوع پرسش و دو مدل قناری و کبوتر - [هما](https://dana.expert/docs/homa): گفت‌وگو به فارسی، پارامترها و محدودیت‌ها - [حساب و کلید API](https://dana.expert/docs/authentication): حساب، کلید `live` و `test` و نگهداری امن آن‌ها - [محدودیت‌ها](https://dana.expert/docs/rate-limits): سقف نرخ و مدیریت `429` --- # مدل‌ها > مدل‌های API دانا، نسخهٔ فعلی و وضعیت دسترسی هر مدل URL: https://dana.expert/docs/models شناسه‌ای که در درخواست می‌فرستید ثابت می‌ماند. نسخهٔ مدلی که جواب داده در فیلد `model_version` پاسخ می‌آید، پس با عوض شدن نسخه کدتان عوض نمی‌شود. | خانواده | مسیر | شناسه در API | نسخهٔ فعلی (`model_version`) | وضعیت | |---|---|---|---|---| | مترجم هدهد | `POST /v1/translate` | `dana-translator` | `hodhod-v2.3` (هدهد v2.3) | در دسترس | | سنجه: قناری | `POST /v1/decide` | `ghanari` (پیش‌فرض) | `ghanari-ir-v0.1` (Ghanari-IR v0.1) | در دسترس | | سنجه: کبوتر | `POST /v1/decide` | `kabootar` | `kabootar-d3-mini` | در دسترس | | هما، گفت‌وگو | `POST /v1/chat/completions` و `POST /v1/messages` | `homa` | `homa-c2b` | در دسترس | اگر مدلی همین حالا در دسترس نباشد، پاسخ `503` با `code` برابر `model_unavailable` است؛ چند دقیقه بعد دوباره بفرستید ([خطاها](https://dana.expert/docs/errors)). ## کجا مدل را انتخاب می‌کنید - **مترجم:** انتخابی لازم نیست؛ همیشه هدهد جواب می‌دهد. - **سنجه:** فیلد اختیاری `model` در بدنه، `ghanari` یا `kabootar`. قناری سریع‌تر است و کبوتر دقیق‌تر. جزئیات در [سنجه](https://dana.expert/docs/decide). - **هما، مدل گفت‌وگو:** فیلد `model` در بدنه برابر `homa`. جزئیات در [هما](https://dana.expert/docs/homa). ## فهرست از خود API `GET /v1/models` با همان کلید، فهرست فعلی را با نسخه و مسیر هر مدل می‌دهد: ```bash curl https://api.dana.expert/v1/models \ -H "Authorization: Bearer $DANA_API_KEY" ``` ```json { "object": "list", "data": [ {"id": "dana-translator", "version": "hodhod-v2.3", "endpoint": "/v1/translate", "status": "available", "object": "model", "owned_by": "dana"}, {"id": "ghanari", "version": "ghanari-ir-v0.1", "endpoint": "/v1/decide", "status": "available", "object": "model", "owned_by": "dana"}, {"id": "kabootar", "version": "kabootar-d3-mini", "endpoint": "/v1/decide", "status": "available", "object": "model", "owned_by": "dana"}, {"id": "homa", "version": "homa-c2b", "endpoint": "/v1/chat/completions", "status": "available", "object": "model", "owned_by": "dana"}, {"id": "dana-1", "endpoint": "/v1/chat/completions", "status": "coming_soon", "object": "model", "owned_by": "dana"}, {"id": "dana-1-fast", "endpoint": "/v1/chat/completions", "status": "coming_soon", "object": "model", "owned_by": "dana"} ] } ``` شناسه‌های `dana-1` و `dana-1-fast` هنوز باز نیستند و پاسخ `503` با `code` برابر `coming_soon` می‌گیرند. ## مرجع کامل قرارداد این مسیر در [مرجع API](https://dana.expert/docs/api-reference/list-models) آمده است. --- # هدهد، مترجم > ترجمهٔ انگلیسی به فارسی با هدهد: درخواست، لحن، پاسخ و هزینه URL: https://dana.expert/docs/translate `POST /v1/translate` متن انگلیسی را با مترجم هدهد (نسخهٔ فعلی v2.3) به فارسی روان برمی‌گرداند. بلوک‌های کد اصلا به مدل داده نمی‌شوند و همان‌طور برمی‌گردند. مدل برای دست نزدن به کد اینلاین، عدد، لینک و اصطلاح فنی آموزش دیده و خروجی‌اش برای کد اینلاین بررسی می‌شود، ولی بی‌خطا نیست. بخشی که درست ترجمه نشود انگلیسی می‌ماند و `fallback` در پاسخ `true` می‌شود. در آزمون خود مدل روی ۱۲۰ متن، ۱۶ متن دست‌کم یک خطا داشتند؛ حذف کد هم ثبت شده است. این سنجش با رفتار محافظتی API فرق دارد. خروجی نهایی را پیش از استفاده بررسی کنید. ``` POST https://api.dana.expert/v1/translate ``` ## نمونه ```bash curl https://api.dana.expert/v1/translate \ -H "Authorization: Bearer $DANA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"text": "The meeting moved to Tuesday.", "register": "auto"}' ``` پاسخ: ```json { "text": "جلسه به روز سه‌شنبه موکول شد.", "register": "formal", "model": "dana-translator", "model_version": "hodhod-v2.3", "fallback": false, "usage": {"prompt_tokens": 6, "completion_tokens": 22, "total_tokens": 28} } ``` ## بدنهٔ درخواست | فیلد | الزامی | توضیح | |---|---|---| | `text` | بله | متن انگلیسی، تا ۲۰٬۰۰۰ کاراکتر | | `direction` | نه | فعلا فقط `en-fa` (پیش‌فرض) | | `register` | نه | لحن ترجمه: `auto` (پیش‌فرض)، `formal` یا `informal` | ## لحن - `formal`: رسمی، با «شما». - `informal`: خودمانی، با «تو». - `auto`: لحن را از خود متن تشخیص می‌دهد و اگر مطمئن نباشد رسمی می‌نویسد. ## پاسخ | فیلد | توضیح | |---|---| | `text` | ترجمهٔ فارسی | | `register` | لحنی که به کار رفت؛ با `auto` همان است که مترجم تشخیص داده | | `model` | همیشه `dana-translator` | | `model_version` | نسخهٔ مترجمی که جواب داده، الان `hodhod-v2.3` (هدهد v2.3) | | `fallback` | `true` یعنی بخشی از متن ترجمه نشد و انگلیسی ماند | | `usage` | توکن‌های ورودی و خروجی همین درخواست | ## هزینه و محدودیت توکن‌های متن ورودی و ترجمه از اعتبار کم می‌شوند: هر یک میلیون توکن ورودی ۱۰٬۰۰۰ تومان و خروجی ۴۰٬۰۰۰ تومان ([قیمت و توکن](https://dana.expert/docs/pricing-and-tokens)). سقف درخواست همان سقف کلید است ([محدودیت‌ها](https://dana.expert/docs/rate-limits)). متن شما و ترجمه‌اش جایی ذخیره نمی‌شوند؛ فقط تعداد توکن‌ها ثبت می‌شود. ## خطاها | کد | یعنی | |---|---| | `400` | `text` خالی، بیش از اندازه، یا `direction` و `register` نامعتبر | | `401` | کلید نیست یا شناخته نشد | | `429` | سقف درخواست یا اعتبار تمام شده | | `503` | با `code` برابر `model_unavailable`: مترجم همین حالا در دسترس نیست؛ چند دقیقه بعد دوباره بفرستید. با `coming_soon`: سرویس موقتا خاموش است | شرح کامل هر کد در [خطاها](https://dana.expert/docs/errors) است. فیلدها و نمونه‌ها به شکل قرارداد در [مرجع API](https://dana.expert/docs/api-reference/translate) هم آمده‌اند. --- # سنجه، مدل‌های تصمیم > تصمیم‌های بسته روی متن فارسی با سنجه: مدل‌ها، سه نوع پرسش، نمونه و محدودیت‌ها URL: https://dana.expert/docs/decide سنجه متن فارسی را می‌خواند و به پرسش‌های بسته جواب می‌دهد: یک گزینه از چند گزینه، بله یا خیر، یا یک پله روی یک طیف. متن تولید نمی‌کند؛ در یک گذر برای هر گزینه احتمال برمی‌گرداند. کاربردهای رایجش دسته‌بندی تیکت، مسیریابی درخواست، تشخیص شکایت، تحلیل نظر و بررسی محتواست. ``` POST https://api.dana.expert/v1/decide ``` ## مدل‌ها | مدل | مقدار `model` | اندازه | دقت | مناسب برای | |---|---|---|---|---| | قناری (پیش‌فرض) | `ghanari` | حدود ۰٫۸ میلیارد پارامتر | ۶۵٪ | حجم بالا و جواب سریع، مثل بررسی ورودی و مسیریابی درخواست | | کبوتر | `kabootar` | حدود ۴ میلیارد پارامتر | ۸۰٪ | تصمیم‌هایی که دقت در آن‌ها از سرعت مهم‌تر است | | شاهین | - | حدود ۹ میلیارد پارامتر | - | به‌زودی | دقت میانگین روی ۱٬۲۰۰ پرسش فارسی از ۱۲ مجموعه‌داده است که در ساخت مدل‌ها نبوده‌اند (سنجش داخلی دانا، مهر ۱۴۰۵). روی دادهٔ شما ممکن است بیشتر یا کمتر باشد. ### کدام را انتخاب کنم - با قناری شروع کنید. پیش‌فرض است و زودتر جواب می‌دهد. - اگر جواب اشتباه برایتان گران است یا پرسش‌ها ظریف‌اند، `"model": "kabootar"` بفرستید. - هر دو را روی چند ده نمونه از دادهٔ خودتان امتحان کنید و آستانهٔ `confidence` را از روی همان بگذارید. ## نمونه ```bash curl https://api.dana.expert/v1/decide \ -H "Authorization: Bearer $DANA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "state": "سه روز است سفارشم را پرداخت کرده‌ام ولی هنوز ارسال نشده.", "questions": { "dept": {"type": "choice", "instructions": "مربوط به کدام بخش است؟", "criteria": ["مالی", "فنی", "ارسال کالا"]}, "complaint": {"type": "noul", "instructions": "آیا این پیام شکایت است؟"}, "anger": {"type": "score", "instructions": "نویسنده چقدر عصبانی است؟", "criteria": ["آرام", "کمی ناراحت", "عصبانی"]} } }' ``` پاسخ: ```json { "model": "ghanari", "model_version": "ghanari-ir-v0.1", "answers": { "dept": {"type": "choice", "choice": "ارسال کالا", "probabilities": {"مالی": 0.0181, "فنی": 0.0203, "ارسال کالا": 0.9616}, "confidence": 0.8278}, "complaint": {"type": "noul", "noul": 0.9521, "confidence": 0.9521}, "anger": {"type": "score", "score": 1.7202, "legend": {"0": "آرام", "1": "کمی ناراحت", "2": "عصبانی"}, "probabilities": {"0": 0.0283, "1": 0.2232, "2": 0.7485}, "confidence": 0.406} }, "usage": {"input_tokens": 218, "output_tokens": 0}, "latency_ms": 78.2 } ``` ## بدنهٔ درخواست | فیلد | توضیح | |---|---| | `state` | متنی که دربارهٔ آن تصمیم گرفته می‌شود؛ رشته یا هر JSON، تا ۲۰٬۰۰۰ کاراکتر | | `questions` | پرسش‌ها با نامی که خودتان می‌گذارید، از ۱ تا ۳۲ پرسش در هر درخواست | | `model` | اختیاری: `ghanari` (قناری، پیش‌فرض و سریع‌تر) یا `kabootar` (کبوتر، دقیق‌تر). نسخهٔ مدلی که جواب داده در فیلد `model_version` پاسخ می‌آید | ## سه نوع پرسش | `type` | `criteria` | جواب | |---|---|---| | `choice` | فهرست گزینه‌ها، یا شیئی از گزینه به توضیح آن | `choice` گزینهٔ برنده و `probabilities` احتمال هر گزینه | | `noul` | ندارد (بله یا خیر) | `noul` احتمال «بله» | | `score` | فهرست مرتب پله‌ها، از کم به زیاد | `score` عددی از ۰ تا شمارهٔ آخرین پله | `instructions` متن پرسش است. کوتاه و روشن بنویسید. `confidence` اطمینان مدل به جوابش است، نه تضمین درستی آن. `usage` در پاسخ، توکن‌هایی است که خود مدل خوانده است. هزینه با شمارش دانا حساب می‌شود (بخش بعد). ## محدودیت‌ها و هزینه - `state` رشته یا هر دادهٔ JSON است، تا ۲۰٬۰۰۰ کاراکتر. - هر درخواست ۱ تا ۳۲ پرسش دارد. - فقط پرسش بسته: سنجه متن نمی‌نویسد و جواب آزاد نمی‌دهد. برای متن فارسی ساخته شده است. - توکن‌های `state` و پرسش‌ها ورودی حساب می‌شوند و هر پرسش یک توکن خروجی. هر یک میلیون توکن ۱۰٬۰۰۰ تومان است ([قیمت و توکن](https://dana.expert/docs/pricing-and-tokens)). - سقف درخواست همان سقف کلید است ([محدودیت‌ها](https://dana.expert/docs/rate-limits)). - متن شما ذخیره نمی‌شود؛ فقط تعداد توکن‌ها ثبت می‌شود. ## خطاها | کد | یعنی | |---|---| | `400` | `state` یا `questions` نیست، یا پرسشی درست تعریف نشده؛ پیام خطا می‌گوید کدام | | `401` | کلید نیست یا شناخته نشد | | `429` | سقف درخواست یا اعتبار تمام شده | | `503` | با `code` برابر `model_unavailable`: سنجه همین حالا در دسترس نیست؛ چند دقیقه بعد دوباره بفرستید. با `coming_soon`: سرویس موقتا خاموش است | شرح کامل هر کد در [خطاها](https://dana.expert/docs/errors) و قرارداد کامل مسیر در [مرجع API](https://dana.expert/docs/api-reference/decide) است. --- # هما، گفت‌وگو > گفت‌وگوی فارسی با هما: کاربرد، نمونه، پارامترهای مهم و محدودیت‌ها URL: https://dana.expert/docs/homa هما مدل گفت‌وگوی فارسی دانا است: مدلی کوچک، با حدود ۲ میلیارد پارامتر، که برای گفت‌وگو به فارسی ساخته شده است. برای کارهای کوتاه و روزمره مناسب است، مثل بازنویسی رسمی یا خودمانی یک متن، خلاصهٔ کوتاه، پیش‌نویس پیام و جواب به پرسش‌های ساده. مدل کوچکی است و ممکن است با اطمینان جواب نادرست بدهد. برای دانستنی‌هایی که باید درست باشند، محاسبهٔ دقیق، کد و استدلال طولانی به آن تکیه نکنید و خروجی را پیش از استفاده بررسی کنید. ``` POST https://api.dana.expert/v1/chat/completions POST https://api.dana.expert/v1/messages ``` هر دو مسیر با `"model": "homa"` به هما می‌رسند. اولی سازگار با OpenAI است و دومی سازگار با Anthropic، و هر دو استریم دارند. ## نمونه **curl:** ```bash curl https://api.dana.expert/v1/chat/completions \ -H "Authorization: Bearer $DANA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "homa", "messages": [{"role": "user", "content": "این جمله را رسمی‌تر بنویس: «فردا جلسه رو کنسل کن.»"}], "max_tokens": 200 }' ``` **Python:** ```python import os from openai import OpenAI client = OpenAI(base_url="https://api.dana.expert/v1", api_key=os.environ["DANA_API_KEY"]) r = client.chat.completions.create( model="homa", messages=[{"role": "user", "content": "این جمله را رسمی‌تر بنویس: «فردا جلسه رو کنسل کن.»"}], max_tokens=200, ) print(r.choices[0].message.content) ``` **JavaScript:** ```js import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.dana.expert/v1", apiKey: process.env.DANA_API_KEY, }); const r = await client.chat.completions.create({ model: "homa", messages: [{ role: "user", content: "این جمله را رسمی‌تر بنویس: «فردا جلسه رو کنسل کن.»" }], max_tokens: 200, }); console.log(r.choices[0].message.content); ``` پاسخ، با فیلدهای اصلی: ```json { "object": "chat.completion", "model": "homa", "choices": [ {"index": 0, "message": {"role": "assistant", "content": "جلسهٔ فردا لغو شود."}, "finish_reason": "stop"} ], "usage": {"prompt_tokens": 32, "completion_tokens": 11, "total_tokens": 43} } ``` با anthropic SDK هم همین کار را می‌کنید: `base_url` را `https://api.dana.expert` بگذارید، بدون `/v1`، و `model="homa"` بفرستید. جزئیات دو رابط در [Chat Completions](https://dana.expert/docs/chat-completions) و [Messages](https://dana.expert/docs/messages) است. ## پارامترهای مهم | پارامتر | توضیح | |---|---| | `model` | `homa` | | `messages` | پیام‌های گفت‌وگو، به ترتیب؛ پیام `system` هم پذیرفته می‌شود | | `max_tokens` | سقف توکن خروجی؛ پیش‌فرض و حداکثر ۴٬۰۹۶. عدد بزرگ‌تر به ۴٬۰۹۶ کم می‌شود | | `temperature` و `top_p` | تنوع خروجی | | `stream` | `true` یعنی پاسخ استریم با SSE | | `stop` | توالی‌هایی که تولید را متوقف می‌کنند | اعتبار به اندازهٔ ورودی به‌علاوهٔ `max_tokens` رزرو می‌شود و بعد از پاسخ، باقی‌اش برمی‌گردد. عددی بگذارید که واقعا لازم دارید ([قیمت و توکن](https://dana.expert/docs/pricing-and-tokens)). ## محدودیت‌ها و هزینه - فقط متن: ورودی و خروجی متنی است. - خروجی هر پاسخ تا ۴٬۰۹۶ توکن است و ورودی و خروجی هر درخواست روی هم تا ۸٬۱۹۲ توکن جا می‌گیرد. گفت‌وگوی بلندتر را کوتاه یا خلاصه کنید. - هر یک میلیون توکن ورودی ۱۰٬۰۰۰ تومان و هر یک میلیون توکن خروجی ۴۰٬۰۰۰ تومان است ([قیمت و توکن](https://dana.expert/docs/pricing-and-tokens)). - سقف درخواست همان سقف کلید است ([محدودیت‌ها](https://dana.expert/docs/rate-limits)). - هما وقتی مدتی استفاده نشود از حافظه خارج می‌شود؛ اولین درخواست بعد از آن چند ثانیه بیشتر طول می‌کشد. ## خطاها | کد | یعنی | |---|---| | `400` | بدنهٔ درخواست درست نیست، مثلاً `messages` ندارد | | `401` | کلید نیست یا شناخته نشد | | `429` | سقف درخواست یا اعتبار تمام شده | | `503` | با `code` برابر `model_unavailable`: هما همین حالا در دسترس نیست؛ چند دقیقه بعد دوباره بفرستید | شرح کامل هر کد در [خطاها](https://dana.expert/docs/errors) و قرارداد کامل دو مسیر در [مرجع API](https://dana.expert/docs/api-reference/chat-completions) است. --- # Chat Completions > رابط سازگار با OpenAI دانا: پارامترها، streaming، هدرها و ساختار پاسخ URL: https://dana.expert/docs/chat-completions `POST /v1/chat/completions` رابط اصلی سازگار با OpenAI است. اگر کدی دارید که با openai SDK کار می‌کند، فقط `base_url` و کلید را عوض کنید. مدل این رابط امروز `homa` است. کاربرد هما و محدودیت‌هایش در [هما](https://dana.expert/docs/homa) آمده است. ``` POST https://api.dana.expert/v1/chat/completions ``` ## نمونه کامل **curl:** ```bash curl https://api.dana.expert/v1/chat/completions \ -H "Authorization: Bearer $DANA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "homa", "messages": [ {"role": "system", "content": "دستیار فارسی‌زبان هستید."}, {"role": "user", "content": "پایتخت ایران کجاست؟"} ] }' ``` **Python:** ```python import os from openai import OpenAI client = OpenAI( api_key=os.environ["DANA_API_KEY"], base_url="https://api.dana.expert/v1", ) response = client.chat.completions.create( model="homa", messages=[ {"role": "system", "content": "دستیار فارسی‌زبان هستید."}, {"role": "user", "content": "پایتخت ایران کجاست؟"}, ], ) print(response.choices[0].message.content) ``` **Node.js:** ```js import OpenAI from "openai"; const client = new OpenAI({ apiKey: process.env.DANA_API_KEY, baseURL: "https://api.dana.expert/v1", }); const response = await client.chat.completions.create({ model: "homa", messages: [ { role: "system", content: "دستیار فارسی‌زبان هستید." }, { role: "user", content: "پایتخت ایران کجاست؟" }, ], }); console.log(response.choices[0].message.content); ``` ## پارامترها فقط دو پارامتر اجباری است: | پارامتر | نوع | توضیح | |---|---|---| | `model` | string | شناسهٔ مدل: `homa` | | `messages` | array | آرایه پیام‌های مکالمه | بقیه اختیاری‌اند: | پارامتر | نوع | توضیح | |---|---|---| | `stream` | boolean | پاسخ به شکل SSE؛ پیش‌فرض `false` | | `max_tokens` | integer | سقف توکن خروجی | | `max_completion_tokens` | integer | نام تازه‌تر همان `max_tokens` | | `temperature` | number | تنوع خروجی، از ۰ تا ۲ | | `top_p` | number | nucleus sampling | | `n` | integer | تعداد پاسخ‌های موازی | | `stop` | string یا array | توالی‌های توقف | | `seed` | integer | برای خروجی تکرارپذیرتر | | `response_format` | object | مثلا حالت JSON | | `tools` | array | تعریف ابزارها برای tool calling | | `tool_choice` | string یا object | انتخاب اجباری یا خودکار ابزار | | `parallel_tool_calls` | boolean | اجازه فراخوانی هم‌زمان چند ابزار | | `frequency_penalty` | number | کم کردن تکرار واژه | | `presence_penalty` | number | تشویق به موضوع تازه | | `logprobs` | boolean | برگرداندن احتمال توکن‌ها | | `top_logprobs` | integer | چند گزینه برتر در `logprobs` | | `logit_bias` | object | دست بردن در شانس توکن‌های مشخص | | `user` | string | شناسه کاربر نهایی برای پیگیری | پارامتری که در این فهرست نیست هم دور ریخته نمی‌شود؛ دانا آن را دست‌نخورده به بک‌اند مدل می‌فرستد. سقف `max_tokens` هم یک حد بالای سمت سرور دارد و مقدار بزرگ‌تر تا همان حد کوتاه می‌شود. ### ساختار پیام ```json {"role": "system", "content": "متن پیام"} ``` مقدار `role` یکی از `system` و `user` و `assistant` است. ## هدرهای اختصاصی دانا | هدر | مقدار | کار | |---|---|---| | `X-Dana-Harness` | `none` یا `base` یا `agent` | پروفایل بهبود فارسی؛ پیش‌فرض `base` | | `X-Dana-Effort` | `low` تا `max` | میزان تلاش مدل و سقف پیش‌فرض خروجی | مقدار نامعتبر روی هرکدام، `400` می‌گیرد. روی `homa` این دو هدر اثری ندارند و سقف خروجی ۴٬۰۹۶ توکن است. ## Streaming با `"stream": true` پاسخ به شکل رویدادهای SSE می‌آید: ```bash curl https://api.dana.expert/v1/chat/completions \ -H "Authorization: Bearer $DANA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"homa","stream":true,"messages":[{"role":"user","content":"یک داستان کوتاه بگو"}]}' ``` هر رویداد یک خط `data:` است و استریم با `[DONE]` تمام می‌شود: ``` data: {"id":"chatcmpl-xyz","object":"chat.completion.chunk","choices":[{"delta":{"content":"یک"},"index":0}]} data: [DONE] ``` آمار مصرف در رویداد پایانی استریم می‌آید، نه در تک‌تک چانک‌ها. ## ساختار پاسخ ```json { "id": "chatcmpl-abc123", "object": "chat.completion", "created": 1700000000, "model": "homa", "choices": [ { "index": 0, "message": {"role": "assistant", "content": "تهران پایتخت ایران است."}, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 22, "completion_tokens": 10, "total_tokens": 32 } } ``` مقدار `finish_reason` می‌گوید چرا تولید ایستاد. `stop` یعنی پاسخ کامل شد و `length` یعنی به سقف `max_tokens` خورده است. اگر پاسخ‌ها نصفه می‌مانند، سراغ همین فیلد بروید. ## صفحه‌های مرتبط - [شروع سریع](https://dana.expert/docs/quickstart) - نخستین درخواست موفق - [Messages](https://dana.expert/docs/messages) - همین کار با رابط Anthropic - [خطاها](https://dana.expert/docs/errors) - هر کد خطا و راه‌حلش - [قیمت و توکن](https://dana.expert/docs/pricing-and-tokens) - معنی `usage` --- # Messages > رابط سازگار با Anthropic دانا برای ارسال پیام، tool calling و شمارش توکن URL: https://dana.expert/docs/messages دانا رابط Anthropic را روی بک‌اند OpenAI-compatible خودش سرو می‌کند. یعنی کدی که با anthropic SDK نوشته‌اید، فقط با عوض کردن `base_url` و کلید کار می‌کند. مدل این رابط امروز `homa` است. کاربرد هما و محدودیت‌هایش در [هما](https://dana.expert/docs/homa) آمده است. ``` POST https://api.dana.expert/v1/messages POST https://api.dana.expert/v1/messages/count_tokens ``` مهم‌ترین نکته تنظیمات: مقدار `base_url` را روی `https://api.dana.expert` بگذارید، **بدون** `/v1`. خود SDK مسیر `/v1/messages` را اضافه می‌کند. رابط [Chat Completions](https://dana.expert/docs/chat-completions) برعکس است و `/v1` می‌خواهد. ## نمونه کامل **curl:** ```bash curl https://api.dana.expert/v1/messages \ -H "Authorization: Bearer $DANA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "homa", "max_tokens": 256, "system": "دستیار فارسی‌زبان هستید.", "messages": [{"role": "user", "content": "سلام دانا!"}] }' ``` **Python:** ```python import os import anthropic client = anthropic.Anthropic( api_key=os.environ["DANA_API_KEY"], base_url="https://api.dana.expert", ) message = client.messages.create( model="homa", max_tokens=256, system="دستیار فارسی‌زبان هستید.", messages=[{"role": "user", "content": "سلام دانا!"}], ) print(message.content[0].text) ``` **Node.js:** ```js import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic({ apiKey: process.env.DANA_API_KEY, baseURL: "https://api.dana.expert", }); const message = await client.messages.create({ model: "homa", max_tokens: 256, system: "دستیار فارسی‌زبان هستید.", messages: [{ role: "user", content: "سلام دانا!" }], }); console.log(message.content[0].text); ``` ## پارامترها | پارامتر | نوع | اجباری | توضیح | |---|---|---|---| | `model` | string | بله | شناسهٔ مدل: `homa` | | `messages` | array | بله | آرایه پیام‌های مکالمه | | `max_tokens` | integer | بله | سقف توکن خروجی | | `system` | string یا array | خیر | پیام system | | `stream` | boolean | خیر | پاسخ به شکل SSE؛ پیش‌فرض `false` | | `temperature` | number | خیر | تنوع خروجی | | `top_p` | number | خیر | nucleus sampling | | `stop_sequences` | array | خیر | توالی‌هایی که تولید را متوقف می‌کنند | | `tools` | array | خیر | تعریف ابزارها با `input_schema` | | `tool_choice` | object | خیر | `auto` یا `any` یا یک ابزار مشخص | برخلاف رابط OpenAI، اینجا `max_tokens` اجباری است. همین یک قلم، رایج‌ترین علت `400` روی این مسیر است. از میان پارامترهای sampling، فقط `temperature` و `top_p` به بک‌اند مدل می‌رسند. مقدار `top_k` پذیرفته می‌شود ولی اثری ندارد، چون بک‌اند مدل معادلی برایش ندارد. ## ساختار پاسخ ```json { "id": "msg_abc123", "type": "message", "role": "assistant", "model": "homa", "content": [{"type": "text", "text": "سلام! چطور می‌توانم کمکتان کنم؟"}], "stop_reason": "end_turn", "usage": {"input_tokens": 18, "output_tokens": 14} } ``` فیلد `content` همیشه آرایه است، حتی برای یک پاسخ متنی ساده. ## Streaming با `"stream": true` استریم رویدادهای Anthropic را می‌گیرید، به همان ترتیب همیشگی: | رویداد | چه وقت | |---|---| | `message_start` | آغاز پاسخ، همراه با شناسه و توکن ورودی | | `content_block_delta` | هر چانک متن یا هر چانک از آرگومان‌های ابزار | | `message_delta` | پایان تولید، همراه با `stop_reason` و توکن خروجی | | `message_stop` | پایان استریم | روی tool calling، آرگومان‌های ابزار به شکل `input_json_delta` تکه‌تکه می‌آیند و باید کنار هم چسبانده شوند. anthropic SDK این کار را خودش می‌کند. ## شمارش توکن پیش از ارسال ```bash curl https://api.dana.expert/v1/messages/count_tokens \ -H "Authorization: Bearer $DANA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "homa", "system": "دستیار فارسی‌زبان هستید.", "messages": [{"role": "user", "content": "سلام دانا!"}] }' ``` پاسخ: ```json {"input_tokens": 18} ``` این عدد فقط ورودی را می‌شمارد و یک برآورد است. شرح کاملش در [قیمت و توکن](https://dana.expert/docs/pricing-and-tokens) آمده است. ## صفحه‌های مرتبط - [شروع سریع](https://dana.expert/docs/quickstart) - نخستین درخواست موفق - [حساب و کلید API](https://dana.expert/docs/authentication) - هدر `x-api-key` هم پذیرفته می‌شود - [خطاها](https://dana.expert/docs/errors) - فرمت خطای Anthropic و همه کدها - [محدودیت‌ها](https://dana.expert/docs/rate-limits) - سقف نرخ درخواست --- # حساب و کلید API > ساخت حساب، شارژ اعتبار، ساخت کلید و فرستادن آن با هر درخواست URL: https://dana.expert/docs/authentication هر درخواست به API دانا باید یک کلید معتبر همراه داشته باشد. کلید به حساب شما وصل است و هزینهٔ درخواست‌ها از اعتبار همین حساب کم می‌شود. ## حساب 1. در [کنسول دانا](https://console.dana.expert) وارد شوید. ورود با شمارهٔ موبایل یا ایمیل است؛ اگر حساب ندارید، با رمز یک‌بارمصرف ساخته می‌شود. 2. از [بخش اعتبار](https://console.dana.expert/credit) حساب را با درگاه پرداخت ایرانی شارژ کنید. 3. در [بخش کلیدها](https://console.dana.expert/keys) کلید بسازید. مصرف و موجودی را در [گزارش مصرف](https://console.dana.expert/usage) ببینید. قیمت هر مدل در [قیمت و توکن](https://dana.expert/docs/pricing-and-tokens) آمده است. برای پرسش دربارهٔ حساب به [info@dana.expert](mailto:info@dana.expert) بنویسید. ## کلید را چطور بفرستید راه اصلی، هدر `Authorization` است: ``` Authorization: Bearer $DANA_API_KEY ``` ```bash curl https://api.dana.expert/v1/translate \ -H "Authorization: Bearer $DANA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"text": "Hello"}' ``` هدر `x-api-key` هم پذیرفته می‌شود و همان کلید را می‌گیرد. SDK رسمی Anthropic به‌طور پیش‌فرض همین را می‌فرستد، پس روی رابط [Messages](https://dana.expert/docs/messages) کاری لازم نیست بکنید. اگر هر دو هدر را بفرستید، `Authorization` مقدم است. ## انواع کلید | پیشوند | محیط | کاربرد | |---|---|---| | `dn-live-` | live | درخواست‌های واقعی، کسر اعتبار | | `dn-test-` | test | تست، بدون کسر اعتبار | کلیدهای test برای توسعه و تست‌اند و کلیدهای live برای پروداکشن. ## مدیریت کلید کلیدها را در [کنسول دانا](https://console.dana.expert/keys) بسازید، نام بگذارید و باطل کنید. سه نکتهٔ عملی: - هر کلید یک بار به‌صورت کامل نمایش داده می‌شود. بعد از بستن پنجره ساخت، دیگر قابل بازیابی نیست و باید کلید تازه بسازید. - کلید باطل‌شده تا حدود ۳۰ ثانیه ممکن است هنوز کار کند، چون نتیجه احراز هویت کوتاه‌مدت کش می‌شود. برای قطع فوری، کلید سرویس را هم عوض کنید. - سقف نرخ روی خودِ کلید تنظیم می‌شود، نه روی حساب. پیش‌فرض ۶۰ درخواست در دقیقه است و شرحش در [محدودیت‌ها](https://dana.expert/docs/rate-limits) آمده. ## نگهداری امن - کلید را در متغیر محیطی یا secrets manager بگذارید، نه داخل کد و نه در ریپوی گیت. - برای هر سرویس و هر محیط یک کلید جدا بسازید. آن‌وقت باطل کردن یکی، بقیه را نمی‌خواباند. - کلید را در مرورگر یا اپ موبایل نگذارید. هر چه به دست کاربر برسد، لو رفته است؛ درخواست را از سرور خودتان بفرستید. - به کلید مشکوک شدید؟ اول در کنسول باطلش کنید، بعد دنبال علت بگردید. ## وقتی احراز هویت رد می‌شود | کد | پیام | علت | |---|---|---| | `401` | `Missing API key.` | هیچ‌کدام از دو هدر ارسال نشده | | `401` | `Invalid API key.` | کلید شناخته نشد، باطل شده یا ناقص کپی شده | | `403` | - | کلید معتبر است ولی اجازه این مسیر را ندارد | مطمئنید کلید درست است و باز `401` می‌گیرید؟ معمولا یکی از این سه است: - کلمه `Bearer` جا افتاده. - متغیر محیطی خالی مانده. - موقع کپی، یک خط جدید یا فاصله هم آمده. شرح کامل هر کد در [خطاها](https://dana.expert/docs/errors) آمده است. --- # قیمت و توکن > توکن در دانا چطور شمرده می‌شود، اعتبار کی کسر می‌شود و مصرف را کجا ببینید URL: https://dana.expert/docs/pricing-and-tokens دانا بر اساس توکن ورودی و خروجی هر درخواست اعتبار کسر می‌کند. واحد پرداخت تومان است. ## قیمت هر مدل قیمت‌ها به تومان و برای هر یک میلیون توکن است: | مدل | مسیر | ورودی | خروجی | |---|---|---|---| | مترجم هدهد (`dana-translator`) | `POST /v1/translate` | ۱۰٬۰۰۰ | ۴۰٬۰۰۰ | | سنجه (`ghanari` و `kabootar`) | `POST /v1/decide` | ۱۰٬۰۰۰ | ۱۰٬۰۰۰ | | هما (`homa`) | `POST /v1/chat/completions` و `POST /v1/messages` | ۱۰٬۰۰۰ | ۴۰٬۰۰۰ | برای نمونه، اگر ترجمه‌ای ۱۳۰ توکن ورودی و ۲۵۰ توکن خروجی مصرف کند، هزینه‌اش حدود ۱۱ تومان است. هزینهٔ سنجه هم به طول متن و تعداد پرسش‌ها بستگی دارد. مصرف هر درخواست همان لحظه در [گزارش درخواست‌ها](https://console.dana.expert/logs) دیده می‌شود. کسر قطعی از موجودی هر ساعت یک بار، از روی همین گزارش، در دفتر اعتبار ثبت می‌شود. ## توکن چیست توکن کوچک‌ترین واحد متنی است که مدل می‌بیند. نه حرف است و نه دقیقا کلمه؛ چیزی میان این دو. به‌طور تقریبی: - هر ۷۵ کلمه انگلیسی ≈ ۱۰۰ توکن - فارسی معمولا توکن بیشتری نسبت به انگلیسی مصرف می‌کند پس یک متن فارسی و ترجمه انگلیسی‌اش، با اینکه یک حرف می‌زنند، یک اندازه هزینه ندارند. ## چه چیزهایی شمرده می‌شوند در هدهد، متن انگلیسی ورودی است و ترجمهٔ فارسی خروجی. در سنجه، متن و پرسش‌ها ورودی‌اند و هر پرسش یک توکن خروجی حساب می‌شود. در گفت‌وگو با هما، مصرف به این شکل شمرده می‌شود: | بخش | شامل چیست | |---|---| | ورودی | متن system، همه پیام‌های قبلی مکالمه، و پیام تازه کاربر | | خروجی | متنی که مدل تولید می‌کند | سه نکته که معمولا غافلگیر می‌کنند: - **تاریخچه هر بار از نو شمرده می‌شود.** مدل حافظه ندارد؛ در هر درخواست کل مکالمه را دوباره می‌فرستید. مکالمه‌ای که طولانی می‌شود، هر نوبت گران‌تر از نوبت قبل تمام می‌شود. برای مکالمه‌های بلند، پیام‌های قدیمی را خلاصه کنید یا بیندازید دور. - **پیام system هم ورودی است.** یک system prompt بلند، هزینه‌اش را به تک‌تک درخواست‌های آن مکالمه اضافه می‌کند. - **هر پیام کمی سربار ساختاری دارد.** ده پیام کوتاه از یک پیام بلندِ هم‌اندازه، کمی بیشتر توکن مصرف می‌کند. ## برآورد ورودی گفت‌وگو با مسیر `count_tokens` تعداد توکن ورودی را پیش از ارسال می‌سنجید: ```bash curl https://api.dana.expert/v1/messages/count_tokens \ -H "Authorization: Bearer $DANA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "homa", "messages": [{"role": "user", "content": "پایتخت ایران کجاست؟"}] }' ``` پاسخ: ```json {"input_tokens": 12} ``` این عدد یک برآورد است، نه رسید. فقط ورودی را می‌شمارد و خروجی هنوز تولید نشده. برای گزارش قطعی، `usage` پاسخ اصلی را بخوانید. ## مصرف واقعی در پاسخ هر پاسخ موفق فیلد `usage` دارد. نامش در دو رابط فرق می‌کند، معنایش یکی است: **رابط OpenAI:** ```json { "usage": { "prompt_tokens": 22, "completion_tokens": 15, "total_tokens": 37 } } ``` **رابط Anthropic:** ```json { "usage": { "input_tokens": 22, "output_tokens": 15 } } ``` روی پاسخ streaming هم این آمار می‌آید، در رویداد پایانی. ## رزرو اعتبار برای درخواست گفت‌وگو دانا موقع پذیرش درخواست، بدترین حالت هزینه را کنار می‌گذارد: توکن‌های ورودی به‌علاوه سقفی که در `max_tokens` خواسته‌اید. وقتی پاسخ تمام شد، تفاوت این برآورد با مصرف واقعی به موجودی برمی‌گردد. دو نتیجه دارد. اول اینکه دیدن یک افت لحظه‌ای در موجودی طبیعی است. دوم اینکه `max_tokens` بزرگ و بی‌دلیل، تا پایان همان درخواست بخشی از اعتبارتان را قفل نگه می‌دارد. عددی بگذارید که واقعا لازم دارید. اگر اعتبار کافی نباشد، درخواست با `429` و نوع `insufficient_quota` رد می‌شود و در [خطاها](https://dana.expert/docs/errors) شرح داده شده است. ## مشاهده مصرف و شارژ در [کنسول دانا](https://console.dana.expert/usage) می‌توانید: - مصرف روزانه توکن را ببینید - درخواست‌ها را بر اساس مدل فیلتر کنید - گزارش CSV بگیرید - موجودی فعلی را بررسی کنید شارژ اعتبار از [بخش اعتبار کنسول](https://console.dana.expert/credit) با درگاه پرداخت ایرانی انجام می‌شود. ## صفحه‌های مرتبط - [Messages](https://dana.expert/docs/messages) - جزئیات endpoint شمارش توکن - [مدل‌ها](https://dana.expert/docs/models) - انتخاب مدل - [محدودیت‌ها](https://dana.expert/docs/rate-limits) - سقف نرخ درخواست - [خطاها](https://dana.expert/docs/errors) - خطاهای مربوط به اعتبار --- # محدودیت‌ها > سقف نرخ درخواست API دانا، هدرهای پاسخ و روش درست مدیریت خطای ۴۲۹ URL: https://dana.expert/docs/rate-limits هر کلید API سقف نرخ خودش را دارد. پیش‌فرض ۶۰ درخواست در دقیقه است و از رد شدن یک کلید، بقیه کلیدهای شما آسیب نمی‌بینند. ## پنجره چطور شمرده می‌شود شمارش fixed window است، نه sliding window. دقیقه به بازه‌های سرراست تقسیم می‌شود و شمارنده سر هر بازه از صفر شروع می‌کند. این یک نتیجه عملی دارد. فرض کنید ۶۰ درخواست را در ثانیه‌های پایانی یک بازه بفرستید و ۶۰ تای بعدی را در ثانیه‌های آغازین بازه بعد. هر دو دسته می‌گذرند، یعنی برای یک لحظه دو برابر سقف رد شده است. پس بار سنگین را پخش کنید و به مرز پنجره تکیه نکنید. ## هدرهای پاسخ روی ۴۲۹ وقتی از سقف رد شوید، پاسخ `429` این چهار هدر را همراه دارد: | هدر | معنا | |---|---| | `Retry-After` | چند ثانیه دیگر پنجره باز می‌شود | | `X-RateLimit-Limit` | سقف همین کلید | | `X-RateLimit-Remaining` | باقی‌مانده، که اینجا همیشه صفر است | | `X-RateLimit-Reset` | زمان باز شدن پنجره به شکل unix timestamp | بدنه پاسخ روی رابط OpenAI: ```json { "error": { "message": "Rate limit exceeded.", "type": "rate_limit_error", "param": null, "code": null } } ``` ## اول `type` را بخوانید کد `429` چهار علت جدا دارد و دو موردشان با تلاش مجدد حل می‌شوند. پیش از تلاش مجدد، فیلد `type` را نگاه کنید: | مقدار `type` | معنا | تلاش مجدد؟ | |---|---|---| | `rate_limit_error` | سقف نرخ همین کلید | بله، بعد از `Retry-After` | | `capacity_busy` | صف موقت سرویس | بله، بعد از `eta_seconds` | | `insufficient_quota` | اعتبار تمام شده | خیر، باید شارژ کنید | | `window_cap` | سقف پنجره توکن | خیر، تا زمان `reset_at` صبر کنید | شرح کامل هر چهار حالت با نمونه بدنه در [خطاها](https://dana.expert/docs/errors) آمده است. ## مدیریت خطا در کد فاصلهٔ تلاش دوباره را از `Retry-After` بگیرید. کمی تأخیر تصادفی (jitter) هم اضافه کنید تا همهٔ workerها هم‌زمان درخواست نفرستند. ```python import random import time import httpx def call_with_retry(payload, api_key, max_attempts=3): for attempt in range(max_attempts): response = httpx.post( "https://api.dana.expert/v1/chat/completions", headers={"Authorization": f"Bearer {api_key}"}, json=payload, timeout=120, ) if response.status_code != 429: response.raise_for_status() return response.json() kind = response.json().get("error", {}).get("type") if kind not in ("rate_limit_error", "capacity_busy"): raise RuntimeError(f"۴۲۹ غیرقابل تلاش مجدد: {kind}") wait = float(response.headers.get("Retry-After", 2**attempt)) time.sleep(wait + random.random()) raise RuntimeError("سقف نرخ بعد از سه تلاش هنوز باز نشده بود") ``` ## سقف هر کلید سقف روی خودِ کلید می‌نشیند، نه روی حساب. در [کنسول دانا](https://console.dana.expert/keys) می‌توانید برای هر کلید مقدار جداگانه بگذارید. الگویی که معمولا جواب می‌دهد: یک کلید پرسقف برای سرویس اصلی، یک کلید کم‌سقف برای اسکریپت‌های تست. اسکریپتی که از کنترل خارج شود، آن‌وقت فقط سهم خودش را می‌سوزاند. ## نکته‌ها - درخواست‌های ناموفق هم شمرده می‌شوند. شمارش پیش از رسیدن به مدل انجام می‌شود، پس یک `400` هم یک درخواست است. - streaming و non-streaming فرقی ندارند؛ هر کدام یک درخواست‌اند، هرچند پاسخ streaming دقایقی طول بکشد. - شمارش با شناسه کلید انجام می‌شود. چند سرور که یک کلید مشترک دارند، در یک پنجره سهیم‌اند. - برای حجم بالا با پشتیبانی دانا تماس بگیرید. ## صفحه‌های مرتبط - [خطاها](https://dana.expert/docs/errors) - همه کدها و فرمت‌های خطا - [حساب و کلید API](https://dana.expert/docs/authentication) - ساخت و باطل کردن کلید - [قیمت و توکن](https://dana.expert/docs/pricing-and-tokens) - سقف اعتبار و شمارش توکن --- # خطاها > هر کد خطای API دانا، علتش و کاری که باید بکنید، با نمونهٔ فرمت خطا URL: https://dana.expert/docs/errors هر خطا یک پاسخ JSON با کد HTTP درست است. دو رابط دانا دو فرمت خطای جدا دارند: مسیرهای `/v1/messages` فرمت Anthropic می‌گیرند و بقیه مسیرها فرمت OpenAI. ## جدول تشخیص سریع | کد | چه اتفاقی افتاده | کار بعدی | |---|---|---| | `400` | بدنه درخواست ناقص یا نامعتبر است | پیام خطا فیلد مقصر را می‌گوید؛ همان را درست کنید | | `401` | کلید نیست یا شناخته نشد | هدر `Authorization: Bearer ...` را بررسی کنید | | `402` | اعتبار سرویس آپ‌استریم تمام شده | تلاش مجدد بی‌فایده است؛ با پشتیبانی تماس بگیرید | | `403` | کلید معتبر است ولی اجازهٔ این مسیر را ندارد | کلید و مسیر را بررسی کنید | | `404` | مسیر یا منبع وجود ندارد | آدرس و شناسه مدل را بازبینی کنید | | `413` | بدنه درخواست از سقف بزرگ‌تر است | پیام‌ها را کوتاه یا تکه‌تکه کنید | | `429` | نرخ درخواست، ظرفیت، سقف توکن یا اعتبار | به [بخش ۴۲۹](#کد-429-چهار-حالت-جدا) بروید؛ چهار حالت جداگانه دارد | | `500` | خطای پیش‌بینی‌نشده در gateway | با backoff تا سه بار تلاش مجدد کنید | | `502` | gateway به بک‌اند مدل نرسید | تلاش مجدد کنید؛ اگر ادامه داشت گزارش بدهید | | `503` | مدل خواسته‌شده هنوز باز نیست (`coming_soon`) یا مدل همین حالا در دسترس نیست (`model_unavailable`) | `code` را بخوانید. `coming_soon` با تلاش دوباره درست نمی‌شود؛ `model_unavailable` چند دقیقه بعد درست می‌شود | | `504` | بک‌اند مدل به‌موقع جواب نداد | درخواست را کوچک‌تر کنید و دوباره بفرستید | ## فرمت خطا **رابط OpenAI** (`/v1/chat/completions`، `/v1/models` و بقیه): ```json { "error": { "message": "Invalid API key.", "type": "authentication_error", "param": null, "code": null } } ``` `param` همیشه `null` است. فیلد `code` فقط در چند خطای مشخص مقدار می‌گیرد و در بقیه `null` می‌ماند. **رابط Anthropic** (`/v1/messages` و `/v1/messages/count_tokens`): ```json { "type": "error", "error": { "type": "authentication_error", "message": "Invalid API key." } } ``` دقت کنید که فرمت Anthropic یک `type: "error"` در سطح بیرونی هم دارد. SDK رسمی Anthropic روی همین فیلد حساب می‌کند. ### مقدار `type` بر اساس کد | کد | رابط OpenAI | رابط Anthropic | |---|---|---| | `400` | `invalid_request_error` | `invalid_request_error` | | `401` | `authentication_error` | `authentication_error` | | `403` | `permission_error` | `permission_error` | | `404` | `not_found_error` | `not_found_error` | | `409` | `conflict_error` | `api_error` | | `413` | `invalid_request_error` | `request_too_large` | | `429` | `rate_limit_error` | `rate_limit_error` | | بقیه | `api_error` | `api_error` | ## خطاها به تفکیک کد ### `400` - درخواست نامعتبر پیام خطا دقیقا می‌گوید کجا ایراد دارد. رایج‌ترین‌ها: ```json {"error": {"message": "Request body must include a 'messages' array.", "type": "invalid_request_error", "param": null, "code": null}} ``` | پیام | علت | راه‌حل | |---|---|---| | `Request body must include a 'messages' array.` | بدنه JSON نیست یا `messages` ندارد | ساختار بدنه را با [Chat Completions](https://dana.expert/docs/chat-completions) بسنجید | | `Request body must be a JSON object.` | بدنه `count_tokens` آبجکت نیست | یک آبجکت JSON بفرستید | | `Invalid X-Dana-Harness value ...` | مقدار هدر harness اشتباه است | یکی از سه مقدار `none` یا `base` یا `agent` | | `Invalid effort ...` | سطح effort ناشناخته است | چهار سطح مجاز `low` و `medium` و `high` و `max` | خطاهای اعتبارسنجی خودکار (نوع اشتباه یک پارامتر، مثلا `temperature` رشته‌ای) هم همین `400` را می‌گیرند و متن خطا فهرست فیلدهای مقصر را برمی‌گرداند. ### `401` - احراز هویت ناموفق ```json {"error": {"message": "Missing API key.", "type": "authentication_error", "param": null, "code": null}} ``` چهار حالت جدا با چهار پیام جدا: - `Missing API key.` هدر `Authorization` ارسال نشده. - `Invalid API key.` کلید در دیتابیس پیدا نشد؛ شاید غیرفعال شده یا حرفی جا افتاده. - `internal_app key requires X-Dana-User-Id and X-Dana-Session-Id.` مربوط به کلیدهای داخلی است. - `X-Dana-User-Id is only valid with an internal_app key.` این هدر را از درخواست بردارید. اگر کلید تازه ساخته‌اید و همچنان `401` می‌گیرید، فاصله یا خط جدید اضافه در متغیر محیطی را بررسی کنید. شرح کامل را در [حساب و کلید API](https://dana.expert/docs/authentication) بخوانید. ### `402` - اعتبار آپ‌استریم تمام شده ```json {"error": {"message": "Router credit/quota exhausted.", "type": "insufficient_quota", "param": null, "code": "router_credit_exhausted"}} ``` این خطا به حساب شما ربط ندارد؛ مربوط به سرویس آپ‌استریم دانا است. تلاش مجدد جوابش را عوض نمی‌کند. ### `403` - دسترسی ممنوع کلید درست است اما اجازه این مسیر را ندارد. مسیرهای `/internal/...` فقط با کلید `internal_app` باز می‌شوند و برای مصرف‌کننده عمومی API در دسترس نیستند. ### `413` - بدنه بیش از حد بزرگ gateway پیش از خواندن بدنه، `Content-Length` را با سقف کانفیگ‌شده می‌سنجد و درخواست را همان‌جا رد می‌کند. ```json {"error": {"message": "Request body too large.", "type": "invalid_request_error", "param": null, "code": null}} ``` تاریخچه مکالمه را کوتاه کنید یا متن‌های بلند را تکه‌تکه بفرستید. ### کد `429` - چهار حالت جدا `429` چهار علت متفاوت دارد. اول `type` را بخوانید، بعد تصمیم بگیرید. **۱. عبور از نرخ درخواست کلید** - `type: "rate_limit_error"` ```json {"error": {"message": "Rate limit exceeded.", "type": "rate_limit_error", "param": null, "code": null}} ``` این پاسخ چهار هدر هم دارد: - `Retry-After` - `X-RateLimit-Limit` - `X-RateLimit-Remaining` - `X-RateLimit-Reset` به جای عدد ثابت، به `Retry-After` گوش بدهید. جزئیات را در [محدودیت‌ها](https://dana.expert/docs/rate-limits) ببینید. **۲. اتمام اعتبار** - `type: "insufficient_quota"` ```json {"error": {"message": "You have insufficient credit. Please top up your balance.", "type": "insufficient_quota", "param": null, "code": "insufficient_quota"}} ``` تلاش مجدد کمکی نمی‌کند. از [بخش اعتبار کنسول](https://console.dana.expert/credit) شارژ کنید. **۳. رسیدن به سقف پنجره توکن** - `type: "window_cap"` این حالت فرمت مخصوص خودش را دارد و روی رابط OpenAI عینا برگردانده می‌شود: ```json { "error": { "type": "window_cap", "which": "session_4h", "reset_at": "", "upgrade_url": "https://console.dana.expert/plans" } } ``` | فیلد | معنا | |---|---| | `which` | کدام پنجره پر شده: `session_4h` یا `weekly` | | `reset_at` | لحظه دقیق باز شدن پنجره، به وقت UTC | | `upgrade_url` | لینک ارتقای پلن در کنسول | تا رسیدن `reset_at` صبر کنید؛ تلاش زودتر همین جواب را می‌گیرد. روی رابط Anthropic همین خطا با فرمت استاندارد Anthropic و نوع `rate_limit_error` برمی‌گردد. **۴. پرشدن ظرفیت لحظه‌ای** - `type: "capacity_busy"` فیلد `eta_seconds` تخمین زمان خالی شدن صف را می‌دهد؛ این یکی ارزش تلاش مجدد دارد. ### `500` - خطای داخلی ```json {"error": {"message": "Internal server error.", "type": "api_error", "param": null, "code": null}} ``` پاسخ عمدا جزئیات ندارد. `x-request-id` را از هدر پاسخ بردارید و همان را به پشتیبانی بدهید؛ لاگ سمت ما با همین شناسه پیدا می‌شود. ### `502` و `504` - مشکل بک‌اند مدل | کد | پیام | `type` | معنا | |---|---|---|---| | `502` | `Cannot reach the model backend.` | `api_error` | gateway نتوانست به بک‌اند وصل شود | | `504` | `Upstream model timed out.` | `timeout_error` | بک‌اند در مهلت مقرر جواب نداد | هر دو گذرا هستند. روی `504` علاوه بر تلاش مجدد، `max_tokens` را کمتر کنید. ### `503` - سرویس‌دهی مدل روشن نیست ```json {"error": {"message": "Dana model serving is coming soon.", "type": "api_error", "param": null, "code": "coming_soon"}} ``` روی رابط Anthropic: ```json {"type": "error", "error": {"type": "api_error", "message": "Dana model serving is coming soon."}} ``` همین پاسخ را شناسه‌های گفت‌وگویی می‌گیرند که هنوز باز نیستند، مثل `dana-1`. با `"model": "homa"` همین مسیرها جواب می‌دهند. `GET /v1/models` شناسه‌های باز نشده را با `"status": "coming_soon"` نشان می‌دهد. بقیه سرویس سر جایش است: ساخت کلید، شارژ اعتبار و گزارش مصرف کار می‌کنند، و [سنجه](https://dana.expert/docs/decide) و [مترجم](https://dana.expert/docs/translate) هم جواب می‌دهند. تلاش مجدد روی این خطا بی‌فایده است. اگر `/v1/decide` یا `/v1/translate` موقتا خاموش باشند، همین `503` را با `code` برابر `coming_soon` می‌دهند و فقط متن پیام فرق می‌کند. ### `503`، مدل در دسترس نیست اگر مترجم یا سنجه همین حالا جواب ندهد، پاسخ این است: ```json {"error": {"message": "مدل ترجمه الان در دسترس نیست؛ چند دقیقهٔ دیگر دوباره بفرستید. (The translation model is unavailable; retry in a few minutes.)", "type": "service_unavailable", "param": null, "code": "model_unavailable"}} ``` این خطا گذراست و هزینه‌ای از اعتبار کم نمی‌کند. چند دقیقه بعد دوباره بفرستید. ## سیاست تلاش مجدد ```python import random import time import httpx RETRYABLE = {429, 500, 502, 503, 504} def call(payload, api_key, max_attempts=3): for attempt in range(max_attempts): response = httpx.post( "https://api.dana.expert/v1/chat/completions", headers={"Authorization": f"Bearer {api_key}"}, json=payload, timeout=120, ) if response.status_code not in RETRYABLE: response.raise_for_status() return response.json() body = response.json().get("error", {}) # این حالت‌ها با تلاش مجدد درست نمی‌شوند. if body.get("type") == "window_cap" or body.get("code") in ( "coming_soon", "insufficient_quota", ): raise RuntimeError(body.get("message")) wait = float(response.headers.get("Retry-After", 2**attempt)) time.sleep(wait + random.random()) raise RuntimeError("سه تلاش پیاپی ناموفق بود") ``` قاعده‌های پشت این کد: - روی `429` با `type: "rate_limit_error"` یا `capacity_busy` تلاش مجدد کنید، با backoff نمایی و کمی jitter. - روی `429` با `window_cap` یا `insufficient_quota` تلاش مجدد نکنید؛ اولی زمان مشخص دارد، دومی شارژ می‌خواهد. - روی `503` با `code` برابر `coming_soon` تلاش دوباره نکنید؛ این مدل هنوز باز نشده است. - `4xx` غیر از `429` را در کد خودتان مدیریت کنید. همان درخواست، همان جواب. - `x-request-id` هر پاسخ را لاگ کنید. بدون آن، پیگیری یک خطای تک‌باره تقریبا ناممکن است. ## صفحه‌های مرتبط - [شروع سریع](https://dana.expert/docs/quickstart) - نخستین درخواست موفق - [حساب و کلید API](https://dana.expert/docs/authentication) - ریشه بیشتر خطاهای `401` و `403` - [محدودیت‌ها](https://dana.expert/docs/rate-limits) - جزئیات `429` و هدرهای نرخ - [قیمت و توکن](https://dana.expert/docs/pricing-and-tokens) - اعتبار و شمارش توکن --- # مرجع API > همهٔ مسیرهای API دانا با بدنهٔ درخواست، پاسخ و خطاها URL: https://dana.expert/docs/api-reference API دانا روی `https://api.dana.expert` است و با یک کلید کار می‌کند. هر مسیر در این بخش یک صفحه دارد: فیلدهای درخواست، ساختار پاسخ، نمونهٔ کد و خطاهایی که ممکن است برگردد. ## آدرس پایه ``` https://api.dana.expert ``` ## احراز هویت کلید را در هدر `Authorization` بفرستید: ``` Authorization: Bearer dn-live-... ``` کلاینت‌های Anthropic همان کلید را با `x-api-key` هم می‌توانند بفرستند. کلید را از [کنسول دانا](https://console.dana.expert/keys) بسازید؛ جزئیات در [حساب و کلید API](https://dana.expert/docs/authentication) است. ## مسیرها | مسیر | کار | وضعیت | |---|---|---| | [`POST /v1/translate`](https://dana.expert/docs/api-reference/translate) | ترجمهٔ انگلیسی به فارسی با هدهد | در دسترس | | [`POST /v1/decide`](https://dana.expert/docs/api-reference/decide) | تصمیم‌های بسته روی متن فارسی با سنجه | در دسترس | | [`GET /v1/models`](https://dana.expert/docs/api-reference/list-models) | فهرست مدل‌ها و نسخهٔ هر کدام | در دسترس | | [`POST /v1/chat/completions`](https://dana.expert/docs/api-reference/chat-completions) | گفت‌وگو با هما، رابط OpenAI | در دسترس | | [`POST /v1/messages`](https://dana.expert/docs/api-reference/messages) | گفت‌وگو با هما، رابط Anthropic | در دسترس | | [`POST /v1/messages/count_tokens`](https://dana.expert/docs/api-reference/count-tokens) | شمارش توکن پیش از ارسال | در دسترس | ## پاسخ‌ها و خطاها پاسخ موفق JSON است و `200` برمی‌گردد. خطاها هم JSON‌اند و فرمت ثابتی دارند: ```json {"error": {"message": "Invalid API key.", "type": "authentication_error", "param": null, "code": null}} ``` مسیرهای `/v1/messages` فرمت Anthropic را برمی‌گردانند: `{"type": "error", "error": {"type": "...", "message": "..."}}`. فهرست کامل کدها و راه‌حل هرکدام در [خطاها](https://dana.expert/docs/errors) است و سقف درخواست‌ها در [محدودیت‌ها](https://dana.expert/docs/rate-limits). ## برای ابزارهای هوش مصنوعی هر صفحه نسخهٔ Markdown دارد: کافی است به آخر آدرس صفحه `.md` اضافه کنید، مثل [`/docs/api-reference/translate.md`](https://dana.expert/docs/api-reference/translate.md). دکمهٔ «کپی صفحه» بالای هر صفحه همین متن را کپی می‌کند. فهرست همهٔ صفحه‌ها در [`/llms.txt`](https://dana.expert/llms.txt) و متن کامل مستندات در یک فایل در [`/llms-full.txt`](https://dana.expert/llms-full.txt) است. --- # ترجمه > متن انگلیسی را با هدهد به فارسی برمی‌گرداند. بلوک‌های کد دست نمی‌خورند. اگر بخشی درست ترجمه نشود، انگلیسی می‌ماند و `fallback` برابر `true` می‌شود. URL: https://dana.expert/docs/api-reference/translate `POST https://api.dana.expert/v1/translate` ## هدرها | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `Authorization` | string | بله | کلید API از کنسول دانا: `Authorization: Bearer dn-live-...` | | `x-api-key` | string | نه | همان کلید، به‌جای هدر `Authorization` | | `Content-Type` | string | بله | مقدار: `"application/json"` | ## بدنهٔ درخواست | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `text` | string | بله | متن انگلیسی؛ ۱ تا ۲۰٬۰۰۰ کاراکتر | | `direction` | string | نه | جهت ترجمه؛ فعلا فقط `en-fa`؛ مقدار: `"en-fa"`؛ پیش‌فرض: `"en-fa"` | | `register` | string | نه | لحن ترجمه: `formal` با «شما»، `informal` با «تو»، `auto` از روی خود متن؛ مقدار: `"auto"`، `"formal"`، `"informal"`؛ پیش‌فرض: `"auto"` | نمونه: ```json { "text": "The meeting moved to Tuesday.", "register": "auto" } ``` ## پاسخ `200` ترجمهٔ فارسی | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `text` | string | بله | ترجمهٔ فارسی | | `register` | string | بله | لحنی که به کار رفت؛ مقدار: `"auto"`، `"formal"`، `"informal"` | | `model` | string | بله | همیشه `dana-translator`؛ مقدار: `"dana-translator"` | | `model_version` | string | بله | نسخهٔ مترجمی که جواب داد، مثل `hodhod-v2.3` | | `fallback` | boolean | بله | `true` یعنی بخشی از متن انگلیسی ماند | | `usage` | object | بله | توکن‌های همین درخواست | **فیلدهای usage:** | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `prompt_tokens` | integer | بله | توکن‌های ورودی | | `completion_tokens` | integer | بله | توکن‌های خروجی | | `total_tokens` | integer | بله | جمع دو عدد بالا | نمونه: ```json { "text": "جلسه به روز سه‌شنبه موکول شد.", "register": "formal", "model": "dana-translator", "model_version": "hodhod-v2.3", "fallback": false, "usage": { "prompt_tokens": 6, "completion_tokens": 22, "total_tokens": 28 } } ``` ## خطاها | کد | یعنی | |---|---| | `400` | بدنهٔ درخواست درست نیست؛ پیام می‌گوید کدام فیلد | | `401` | کلید نرسید یا شناخته نشد | | `429` | سقف درخواست، ظرفیت یا اعتبار؛ `type` و `code` علت را می‌گویند | | `503` | مدل همین حالا در دسترس نیست (`model_unavailable`)؛ چند دقیقه بعد دوباره بفرستید | فرمت خطا: ```json { "error": { "message": "Request body must include 'text' as a string.", "type": "invalid_request_error", "param": null, "code": null } } ``` --- # تصمیم با سنجه > یک متن یا دادهٔ JSON و چند پرسش بسته می‌گیرد و برای هر پرسش جواب و احتمال گزینه‌ها را برمی‌گرداند. سه نوع پرسش دارد: `choice`، `noul` و `score`. URL: https://dana.expert/docs/api-reference/decide `POST https://api.dana.expert/v1/decide` ## هدرها | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `Authorization` | string | بله | کلید API از کنسول دانا: `Authorization: Bearer dn-live-...` | | `x-api-key` | string | نه | همان کلید، به‌جای هدر `Authorization` | | `Content-Type` | string | بله | مقدار: `"application/json"` | ## بدنهٔ درخواست | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `state` | string \| object \| array | بله | متنی که دربارهٔ آن تصمیم گرفته می‌شود: یک رشته، یا هر دادهٔ JSON؛ تا ۲۰٬۰۰۰ کاراکتر | | `questions` | object | بله | پرسش‌ها: هر کلید نامی است که خودتان می‌گذارید (مثل `dept`) و جواب با همین نام برمی‌گردد؛ ۱ تا ۳۲ کلید | | `model` | string | نه | `ghanari` (قناری، سریع‌تر) یا `kabootar` (کبوتر، دقیق‌تر)؛ مقدار: `"ghanari"`، `"kabootar"`؛ پیش‌فرض: `"ghanari"` | **هر کلید در questions نامی است که خودتان می‌گذارید و مقدارش این فیلدها را دارد:** | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `type` | string | بله | نوع پرسش: `choice` یک گزینه از چند گزینه، `noul` بله یا خیر، `score` یک پله روی طیفی مرتب؛ مقدار: `"choice"`، `"noul"`، `"score"` | | `instructions` | string | بله | متن پرسش؛ کوتاه و روشن، مثل «مربوط به کدام بخش است؟» | | `criteria` | string[] \| object | نه | برای `choice` فهرست گزینه‌ها، یا شیئی از گزینه به توضیح آن؛ برای `score` پله‌ها از کم به زیاد؛ برای `noul` لازم نیست | نمونه: ```json { "state": "سه روز است سفارشم را پرداخت کرده‌ام ولی هنوز ارسال نشده.", "questions": { "dept": { "type": "choice", "instructions": "مربوط به کدام بخش است؟", "criteria": [ "مالی", "فنی", "ارسال کالا" ] }, "complaint": { "type": "noul", "instructions": "آیا این پیام شکایت است؟" }, "anger": { "type": "score", "instructions": "نویسنده چقدر عصبانی است؟", "criteria": [ "آرام", "کمی ناراحت", "عصبانی" ] } } } ``` ## پاسخ `200` جواب هر پرسش | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `model` | string | بله | مدلی که جواب داد: `ghanari` یا `kabootar` | | `model_version` | string | نه | نسخهٔ همان مدل، مثل `ghanari-ir-v0.1` | | `answers` | object | بله | جواب هر پرسش، با همان کلیدی که در `questions` فرستادید | | `usage` | object | نه | توکن‌هایی که خود مدل خواند؛ هزینه با شمارش gateway حساب می‌شود | | `latency_ms` | number | نه | زمان پاسخ مدل به میلی‌ثانیه | **هر کلید در answers نامی است که خودتان می‌گذارید و مقدارش این فیلدها را دارد:** | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `type` | string | بله | مقدار: `"choice"`، `"noul"`، `"score"` | | `choice` | string | نه | برای `choice`: گزینهٔ برنده | | `noul` | number | نه | برای `noul`: احتمال «بله»؛ ۰ تا ۱ | | `score` | number | نه | برای `score`: عددی از ۰ تا شمارهٔ آخرین پله | | `legend` | object | نه | برای `score`: نام هر پله | | `probabilities` | object | نه | احتمال هر گزینه یا پله | | `confidence` | number | بله | اطمینان مدل به جوابش؛ تضمین درستی نیست؛ ۰ تا ۱ | **فیلدهای usage:** | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `input_tokens` | integer | نه | | | `output_tokens` | integer | نه | | نمونه: ```json { "model": "ghanari", "model_version": "ghanari-ir-v0.1", "answers": { "dept": { "type": "choice", "choice": "ارسال کالا", "probabilities": { "مالی": 0.0181, "فنی": 0.0203, "ارسال کالا": 0.9616 }, "confidence": 0.8278 }, "complaint": { "type": "noul", "noul": 0.9521, "confidence": 0.9521 }, "anger": { "type": "score", "score": 1.7202, "legend": { "0": "آرام", "1": "کمی ناراحت", "2": "عصبانی" }, "probabilities": { "0": 0.0283, "1": 0.2232, "2": 0.7485 }, "confidence": 0.406 } }, "usage": { "input_tokens": 218, "output_tokens": 0 }, "latency_ms": 78.2 } ``` ## خطاها | کد | یعنی | |---|---| | `400` | بدنهٔ درخواست درست نیست؛ پیام می‌گوید کدام فیلد | | `401` | کلید نرسید یا شناخته نشد | | `429` | سقف درخواست، ظرفیت یا اعتبار؛ `type` و `code` علت را می‌گویند | | `503` | مدل همین حالا در دسترس نیست (`model_unavailable`)؛ چند دقیقه بعد دوباره بفرستید | فرمت خطا: ```json { "error": { "message": "Request body must include 'text' as a string.", "type": "invalid_request_error", "param": null, "code": null } } ``` --- # فهرست مدل‌ها > فهرست مدل‌های فعلی را با نسخه، مسیر و وضعیت هر مدل می‌دهد. شناسه‌هایی که هنوز باز نیستند وضعیت `coming_soon` دارند. URL: https://dana.expert/docs/api-reference/list-models `GET https://api.dana.expert/v1/models` ## هدرها | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `Authorization` | string | بله | کلید API از کنسول دانا: `Authorization: Bearer dn-live-...` | | `x-api-key` | string | نه | همان کلید، به‌جای هدر `Authorization` | ## پاسخ `200` فهرست مدل‌ها | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `object` | string | بله | مقدار: `"list"` | | `data` | object[] | بله | | **فیلدهای هر عضو data:** | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `id` | string | بله | شناسه‌ای که در درخواست می‌فرستید | | `object` | string | بله | مقدار: `"model"` | | `created` | integer | بله | زمان پاسخ، Unix seconds | | `owned_by` | string | بله | مقدار: `"dana"` | | `endpoint` | string | بله | مسیری که این مدل را سرو می‌کند | | `status` | string | بله | وضعیت مدل؛ مقدار: `"available"`، `"coming_soon"` | | `version` | string | نه | نسخهٔ فعلی؛ برای مدل‌هایی که هنوز باز نشده‌اند نمی‌آید | نمونه: ```json { "object": "list", "data": [ { "id": "dana-translator", "object": "model", "created": 1793000000, "owned_by": "dana", "endpoint": "/v1/translate", "status": "available", "version": "hodhod-v2.3" }, { "id": "ghanari", "object": "model", "created": 1793000000, "owned_by": "dana", "endpoint": "/v1/decide", "status": "available", "version": "ghanari-ir-v0.1" }, { "id": "kabootar", "object": "model", "created": 1793000000, "owned_by": "dana", "endpoint": "/v1/decide", "status": "available", "version": "kabootar-d3-mini" }, { "id": "homa", "object": "model", "created": 1793000000, "owned_by": "dana", "endpoint": "/v1/chat/completions", "status": "available", "version": "homa-c2b" }, { "id": "dana-1", "object": "model", "created": 1793000000, "owned_by": "dana", "endpoint": "/v1/chat/completions", "status": "coming_soon" } ] } ``` ## خطاها | کد | یعنی | |---|---| | `401` | کلید نرسید یا شناخته نشد | فرمت خطا: ```json { "error": { "message": "Invalid API key.", "type": "authentication_error", "param": null, "code": null } } ``` --- # Chat Completions > رابط سازگار با OpenAI برای گفت‌وگو با هما (`"model": "homa"`). خروجی هر پاسخ تا ۴٬۰۹۶ توکن است و ورودی و خروجی روی هم تا ۸٬۱۹۲ توکن. URL: https://dana.expert/docs/api-reference/chat-completions `POST https://api.dana.expert/v1/chat/completions` ## هدرها | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `Authorization` | string | بله | کلید API از کنسول دانا: `Authorization: Bearer dn-live-...` | | `x-api-key` | string | نه | همان کلید، به‌جای هدر `Authorization` | | `Content-Type` | string | بله | مقدار: `"application/json"` | ## بدنهٔ درخواست | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `model` | string | بله | شناسهٔ مدل: `homa` | | `messages` | object[] | بله | تاریخچهٔ گفت‌وگو | | `max_tokens` | integer | نه | سقف توکن خروجی؛ پیش‌فرض و حداکثر ۴٬۰۹۶. عدد بزرگ‌تر به ۴٬۰۹۶ کم می‌شود؛ پیش‌فرض: `4096`؛ حداکثر ۴٬۰۹۶ | | `temperature` | number | نه | ۰ تا ۲ | | `top_p` | number | نه | | | `stream` | boolean | نه | `true` یعنی پاسخ استریم با SSE؛ پیش‌فرض: `false` | | `stop` | string \| string[] | نه | | | `tools` | object[] | نه | ابزارها با ساختار OpenAI | | `tool_choice` | any | نه | انتخاب ابزار با ساختار OpenAI | **فیلدهای هر عضو messages:** | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `role` | string | بله | مقدار: `"system"`، `"user"`، `"assistant"`، `"tool"` | | `content` | string \| object[] | بله | متن پیام یا فهرست بخش‌ها | نمونه: ```json { "model": "homa", "messages": [ { "role": "user", "content": "این جمله را رسمی‌تر بنویس: «فردا جلسه رو کنسل کن.»" } ], "max_tokens": 200 } ``` ## پاسخ `200` پاسخ هما، با ساختار OpenAI | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `id` | string | نه | | | `object` | string | نه | مقدار: `"chat.completion"` | | `created` | integer | نه | | | `model` | string | نه | | | `choices` | object[] | نه | | | `usage` | object | نه | | **فیلدهای هر عضو choices:** | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `index` | integer | نه | | | `message` | object | نه | | | `finish_reason` | string | نه | | **فیلدهای message:** | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `role` | string | بله | مقدار: `"system"`، `"user"`، `"assistant"`، `"tool"` | | `content` | string \| object[] | بله | متن پیام یا فهرست بخش‌ها | **فیلدهای usage:** | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `prompt_tokens` | integer | بله | توکن‌های ورودی | | `completion_tokens` | integer | بله | توکن‌های خروجی | | `total_tokens` | integer | بله | جمع دو عدد بالا | ### هدرهای پاسخ | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `x-dana-cold-start` | string | نه | `1` وقتی هما پیش از این جواب در حافظه بارگذاری شد؛ چنین پاسخی چند ثانیه بیشتر طول کشیده است. در بقیهٔ پاسخ‌ها نمی‌آید. | نمونه: ```json { "id": "chatcmpl-123", "object": "chat.completion", "created": 1793418932, "model": "homa", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "جلسهٔ فردا لغو شود." }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 32, "completion_tokens": 11, "total_tokens": 43 } } ``` ## خطاها | کد | یعنی | |---|---| | `400` | بدنهٔ درخواست درست نیست؛ پیام می‌گوید کدام فیلد | | `401` | کلید نرسید یا شناخته نشد | | `429` | سقف درخواست، ظرفیت یا اعتبار؛ `type` و `code` علت را می‌گویند | | `503` | `model_unavailable`: هما همین حالا در دسترس نیست؛ چند دقیقه بعد دوباره بفرستید. `coming_soon`: شناسهٔ مدلی جز `homa` خواسته‌اید که هنوز باز نیست | فرمت خطا: ```json { "error": { "message": "Request body must include 'text' as a string.", "type": "invalid_request_error", "param": null, "code": null } } ``` --- # Messages > رابط سازگار با Anthropic برای گفت‌وگو با هما (`"model": "homa"`). خروجی هر پاسخ تا ۴٬۰۹۶ توکن است. خطاهای این مسیر فرمت Anthropic دارند. URL: https://dana.expert/docs/api-reference/messages `POST https://api.dana.expert/v1/messages` ## هدرها | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `Authorization` | string | بله | کلید API از کنسول دانا: `Authorization: Bearer dn-live-...` | | `x-api-key` | string | نه | همان کلید، برای کلاینت‌های Anthropic | | `Content-Type` | string | بله | مقدار: `"application/json"` | ## بدنهٔ درخواست | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `model` | string | بله | شناسهٔ مدل: `homa` | | `max_tokens` | integer | بله | سقف توکن خروجی؛ پیش‌فرض و حداکثر ۴٬۰۹۶. عدد بزرگ‌تر به ۴٬۰۹۶ کم می‌شود؛ حداکثر ۴٬۰۹۶ | | `messages` | object[] | بله | | | `system` | string \| object[] | نه | دستور سیستمی | | `temperature` | number | نه | ۰ تا ۱ | | `stream` | boolean | نه | پیش‌فرض: `false` | | `stop_sequences` | string[] | نه | | | `tools` | object[] | نه | ابزارها با ساختار Anthropic | **فیلدهای هر عضو messages:** | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `role` | string | بله | مقدار: `"system"`، `"user"`، `"assistant"`، `"tool"` | | `content` | string \| object[] | بله | متن پیام یا فهرست بخش‌ها | نمونه: ```json { "model": "homa", "max_tokens": 200, "messages": [ { "role": "user", "content": "این جمله را رسمی‌تر بنویس: «فردا جلسه رو کنسل کن.»" } ] } ``` ## پاسخ `200` پاسخ هما، با ساختار Anthropic | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `id` | string | نه | | | `type` | string | نه | مقدار: `"message"` | | `role` | string | نه | مقدار: `"assistant"` | | `model` | string | نه | | | `content` | object[] | نه | | | `stop_reason` | string | نه | | | `usage` | object | نه | | **فیلدهای usage:** | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `input_tokens` | integer | نه | | | `output_tokens` | integer | نه | | ### هدرهای پاسخ | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `x-dana-cold-start` | string | نه | `1` وقتی هما پیش از این جواب در حافظه بارگذاری شد؛ چنین پاسخی چند ثانیه بیشتر طول کشیده است. در بقیهٔ پاسخ‌ها نمی‌آید. | نمونه: ```json { "id": "msg_123", "type": "message", "role": "assistant", "model": "homa", "content": [ { "type": "text", "text": "جلسهٔ فردا لغو شود." } ], "stop_reason": "end_turn", "usage": { "input_tokens": 32, "output_tokens": 11 } } ``` ## خطاها | کد | یعنی | |---|---| | `400` | خطا با فرمت Anthropic؛ `type` و پیام، علت را می‌گویند | | `401` | خطا با فرمت Anthropic؛ `type` و پیام، علت را می‌گویند | | `429` | خطا با فرمت Anthropic؛ `type` و پیام، علت را می‌گویند | | `503` | هما همین حالا در دسترس نیست؛ چند دقیقه بعد دوباره بفرستید | فرمت خطا: ```json { "type": "error", "error": { "type": "authentication_error", "message": "Invalid API key." } } ``` --- # شمارش توکن > تعداد توکن ورودی یک درخواست Messages را پیش از ارسال می‌شمارد. URL: https://dana.expert/docs/api-reference/count-tokens `POST https://api.dana.expert/v1/messages/count_tokens` ## هدرها | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `Authorization` | string | بله | کلید API از کنسول دانا: `Authorization: Bearer dn-live-...` | | `x-api-key` | string | نه | همان کلید، برای کلاینت‌های Anthropic | | `Content-Type` | string | بله | مقدار: `"application/json"` | ## بدنهٔ درخواست | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `model` | string | بله | | | `messages` | object[] | بله | | | `system` | string \| object[] | نه | | | `tools` | object[] | نه | | **فیلدهای هر عضو messages:** | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `role` | string | بله | مقدار: `"system"`، `"user"`، `"assistant"`، `"tool"` | | `content` | string \| object[] | بله | متن پیام یا فهرست بخش‌ها | نمونه: ```json { "model": "homa", "messages": [ { "role": "user", "content": "این جمله را رسمی‌تر بنویس: «فردا جلسه رو کنسل کن.»" } ] } ``` ## پاسخ `200` تعداد توکن ورودی | فیلد | نوع | الزامی | توضیح | |---|---|---|---| | `input_tokens` | integer | بله | تعداد توکن ورودی | نمونه: ```json { "input_tokens": 8 } ``` ## خطاها | کد | یعنی | |---|---| | `400` | خطا با فرمت Anthropic؛ `type` و پیام، علت را می‌گویند | | `401` | خطا با فرمت Anthropic؛ `type` و پیام، علت را می‌گویند | | `503` | هما همین حالا در دسترس نیست؛ چند دقیقه بعد دوباره بفرستید | فرمت خطا: ```json { "type": "error", "error": { "type": "authentication_error", "message": "Invalid API key." } } ```