ملی ای‌پی‌آی

مستندات API هوش مصنوعی

دو نشانی، یک کلید. هر چیزی که در این صفحه است از همان کدی آمده که درخواست شما را پاسخ می‌دهد.

سند OpenAPI OAS 3.0.3

فایل را در Postman یا Swagger وارد کنید، یا از رویش کلاینت تولید کنید. ⚠️ سند در لحظهٔ دانلود ساخته می‌شود، پس فهرست سرویس‌ها و قیمت‌ها همانی است که همان لحظه فعال است.

دانلود سند OpenAPI

احراز هویت

کلید را در هدر Authorization بفرستید. هدر x-api-key هم پذیرفته می‌شود.

Authorization: Bearer melli_live_…

⚠️ کلید فقط سمت سرور نگهداری شود. کلیدی که در جاوااسکریپت مرورگر یا اپلیکیشن موبایل بنشیند، در دسترس هر کسی است که ابزار توسعه‌دهندهٔ مرورگر را باز کند.

اگر IP سرورتان ثابت است، هنگام ساخت کلید فهرست IP مجاز را پر کنید؛ آن‌وقت کلیدِ نشت‌کرده از جای دیگر کار نمی‌کند.

گفت‌وگو با مدل زبانی

POST https://melliapi.net/api/v1/ai/chat/completions/

{
  "model": "gemini-flash",
  "messages": [
    { "role": "system", "content": "پاسخ‌ها را کوتاه و فارسی بده." },
    { "role": "user", "content": "پایتخت ایران کجاست؟" }
  ],
  "max_tokens": 200,
  "temperature": 0.3
}
فیلدلازمتوضیح
modelبلهنام مدل، از جدول «مدل‌های در دسترس».
messagesبلهآرایه‌ای از پیام‌ها. هر پیام role (system | user | assistant) و content دارد. نقش ناشناخته رد می‌شود و بی‌صدا به user تبدیل نمی‌شود.
max_tokensخیرسقف طول پاسخ. بیشتر از سقف مدل بفرستید تا همان سقف کوتاه می‌شود. نفرستید، سقف پیش‌فرض مدل اعمال می‌شود.
temperatureخیرمیزان تنوع پاسخ. نفرستید، پیش‌فرض مدل.
streamخیرtrue یعنی پاسخ تکه‌تکه و به‌صورت SSE بیاید.

پاسخ موفق

{
  "ok": true,
  "requestId": "req_7f3c…",
  "model": "gemini-flash",
  "content": "تهران.",
  "usage": { "promptTokens": 42, "completionTokens": 3 },
  "finishReason": "stop",
  "billing": { "amountRial": 710, "balanceRial": 48912340 }
}

🔴 billing.amountRial مبلغی است که واقعاً کسر شد و نه سقفی که پیش از تماس قفل شده بود. تفاوت این دو همان لحظه به موجودی برمی‌گردد.

requestId را نگه دارید. تنها چیزی است که برای پیگیری یک فراخوان در پشتیبانی به کار می‌آید، چون متن پیام‌ها را نگه نمی‌داریم.

پاسخ جریانی

با فرستادن "stream": true، پاسخ به‌صورت text/event-stream تکه‌تکه می‌آید. هر تکه یک خط data: است.

data: {"requestId":"req_7f3c…","delta":"ته"}

data: {"requestId":"req_7f3c…","delta":"ران."}

data: {"requestId":"req_7f3c…","done":true,"usage":{"promptTokens":42,"completionTokens":3},"billing":{"amountRial":710}}

data: [DONE]

⚠️ صورتحساب در تکهٔ پایانی می‌آید، نه در ابتدا، چون هزینه تا پایان تولید معلوم نیست. اگر ارتباط را وسط کار قطع کنید، بابت همان مقداری که تولید شده هزینه کسر می‌شود؛ مدل تا آن لحظه کار کرده است.

اگر پیش از شروع جریان خطایی رخ دهد، کلید نامعتبر، موجودی ناکافی، مدل خاموش، پاسخ یک JSON معمولی با کد وضعیت مناسب است و نه جریان. پس همیشه content-type را بررسی کنید.

تولید تصویر

POST https://melliapi.net/api/v1/ai/chat/completions/

مدل تصویرساز مسیر جدایی ندارد: همان نشانی و همان بدنهٔ گفت‌وگو، و تصویر در کلید images پاسخ برمی‌گردد. توصیفِ تصویر را مثل یک پیام معمولی بفرستید.

{
  "model": "nano-banana",
  "messages": [
    { "role": "user", "content": "یک فنجان قهوه روی میز چوبی، نور طبیعی" }
  ],
  "max_tokens": 4096
}

پاسخ موفق

{
  "ok": true,
  "requestId": "req_9b1d…",
  "model": "nano-banana",
  "content": "",
  "images": ["data:image/png;base64,iVBORw0KGgo…"],
  "usage": { "promptTokens": 18, "completionTokens": 1290 },
  "billing": { "amountRial": 531300, "balanceRial": 48381040 }
}

🔴 content برای مدل تصویرساز معمولاً خالی است و این طبیعی است؛ خروجی در images است. هر عضو یکdata URI است، پس پاسخ می‌تواند چند مگابایت باشد.

⚠️ قیمت این مدل‌ها هم توکنی است و نه ثابت به‌ازای هر تصویر: تصویر خروجی به توکن شمرده می‌شود. مبلغ کسرشده مثل همیشه درbilling نوشته است، و timeout سمت خودتان را دست‌کم ۱۲۰ ثانیه بگذارید.

مدل‌های متنی برای همین کلید images آرایهٔ خالی می‌دهند، پس لازم نیست دو شکل پاسخ را جدا مدیریت کنید.

ساخت ویدیو

POST https://melliapi.net/api/v1/ai/videos/

درخواست، کار را ثبت می‌کند و پاسخ 202 با شناسهٔ کار برمی‌گرداند، نه خود ویدیو. فیلدها: model و prompt لازم‌اند؛ duration (ثانیه)، resolution، audio و image (تصویر آغازین، نشانی https یا data URL) اختیاری‌اند و مقدارهای مجاز هر مدل در صفحهٔ همان مدل آمده. مقدار ناشناخته رد می‌شود و به نزدیک‌ترین مقدار گرد نمی‌شود.

{
  "model": "google-veo-3.1-fast",
  "prompt": "A slow cinematic drone shot over the Persian Gulf at sunset",
  "duration": 8,
  "resolution": "720p",
  "audio": true
}
{
  "ok": true,
  "id": "vid_3f2a…",
  "status": "processing",
  "billing": { "reservedRial": 1594000, "amountRial": 0 }
}

GET https://melliapi.net/api/v1/ai/videos/{id}/

وضعیت را هر چند ثانیه بپرسید. status یکی از processing، succeeded یا failed است. در حالت موفق videoUrl و expiresAt می‌آیند؛ دریافت فایل از videoUrl همان هدر Authorization را می‌خواهد.

🔴 پول: قیمت ویدیو (نرخ هر ثانیه × مدت) هنگام ثبت از موجودی قفل می‌شود. اگر ساخت موفق شود همان مبلغ کسر می‌شود؛ اگر ناموفق باشد یا در یک ساعت تمام نشود، کامل برمی‌گردد. فایل ویدیو ۷ روز نزد ما می‌ماند و بعد پاک می‌شود؛ آن را نزد خودتان ذخیره کنید.

کاری که failed شود، error.code دارد: generation_failed (ساخت ناموفق)، timeout (در مهلت تمام نشد)، delivery_failed (فایل دریافت نشد) یا temporarily_unavailable. در همهٔ این حالت‌ها مبلغی کسر نمی‌شود.

خطاها

هر پاسخ ناموفق همین شکل را دارد و کد وضعیت HTTP هم با آن می‌خواند:

{
  "ok": false,
  "requestId": "req_7f3c…",
  "error": { "code": "insufficient_funds", "message": "…" },
  "billing": { "amountRial": 0, "balanceRial": 120000 }
}
وضعیتکدمعنا و کاری که باید کرد
۴۰۰invalid_jsonبدنه JSON معتبر نیست. هزینه‌ای ندارد.
۴۰۰invalid_inputنام مدل نیامده، فهرست پیام‌ها نامعتبر است، یا مدل ورودی را رد کرده. هزینه‌ای ندارد.
۴۰۱unauthorizedکلید نیامده یا معتبر نیست. کلید تازه را از پنل بسازید.
۴۰۴not_foundفقط ویدیو: کاری با این شناسه نیست، مال حساب دیگری است، یا فایلش منقضی شده.
۴۲۲provider_rejectedفقط ویدیو: سرویس سازنده توصیف یا تصویر را نپذیرفت. هزینه‌ای ندارد.
۵۰۳temporarily_unavailableفقط ویدیو: ثبت کار ممکن نشد. هزینه‌ای ندارد؛ کمی بعد دوباره بفرستید.
۴۰۳ip_not_allowedIP فراخوان در فهرست مجاز کلید نیست. فهرست را در پنل به‌روز کنید.
۴۰۳model_not_enabledاین مدل همین حالا ارائه نمی‌شود. جدول «مدل‌های در دسترس» را ببینید.
۴۰۳organization_inactiveحساب کسب‌وکار فعال نیست. با پشتیبانی تماس بگیرید.
۴۰۲insufficient_fundsموجودی برای سقف این فراخوان کافی نیست. پیام می‌گوید سقف چقدر است. پنل را شارژ کنید.
۴۰۴unknown_modelچنین مدلی وجود ندارد. املای نام مدل را بررسی کنید.
۴۲۹rate_limitedسقف فراخوان در دقیقه رد شده. به اندازهٔ Retry-After صبر کنید. هزینه‌ای ندارد.
۵۰۳model_unavailableمدل پاسخ نداد یا در مهلت مقرر نرسید. قابل تلاش دوباره. هزینه‌ای ندارد.
۵۰۳ai_disabledارائهٔ هوش مصنوعی موقتاً بسته است. سرویس‌های استعلام مستقل‌اند و باز می‌مانند.
۵۰۳api_disabledارائهٔ API موقتاً به‌کلی بسته است. با پشتیبانی تماس بگیرید.
۵۰۳pricing_unavailableپیکربندی قیمت‌گذاری ناقص است. خطای ماست و نه شما؛ با پشتیبانی تماس بگیرید.
۵۰۰internal_errorخطای پیش‌بینی‌نشدهٔ ما. شناسهٔ درخواست را به پشتیبانی بدهید.

⚠️ 429 هدر Retry-After دارد؛ به‌جای تلاش فوری، همان اندازه صبر کنید.

صورتحساب

  • پیش از تماس با مدل، سقف هزینه از موجودی قفل می‌شود. پس از پاسخ، مبلغ واقعی کسر و باقی همان لحظه آزاد می‌شود.
  • سقف خروجی را با max_tokens خودتان تعیین می‌کنید. اگر نفرستید، سقف پیش‌فرض همان مدل اعمال می‌شود.
  • ورودی نامعتبر، در دسترس نبودن مدل و عبور از سقف نرخ هزینه‌ای ندارند.
  • اگر ارائه‌دهنده شمار توکن را گزارش نکند، فراخوان رایگان حساب می‌شود. ضررش با ماست، نه شما.

برای برآورد پیش از مصرف، ماشین‌حساب قیمت متن خودتان را می‌گیرد و عدد می‌دهد. شرح کلی سرویس و کاربردهایش در صفحهٔ API هوش مصنوعی است.

مدل‌های در دسترس

فهرست مدل‌ها همین حالا در دسترس نیست. برای دریافت فهرست با ما تماس بگیرید.

نمونهٔ کد

curl

curl -X POST 'https://melliapi.net/api/v1/ai/chat/completions/' \
  -H 'Authorization: Bearer melli_live_…' \
  -H 'Content-Type: application/json' \
  -d '{"model":"gemini-flash","messages":[{"role":"user","content":"سلام"}],"max_tokens":200}'

Node.js

const response = await fetch('https://melliapi.net/api/v1/ai/chat/completions/', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.MELLIAPI_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'gemini-flash',
    messages: [{ role: 'user', content: prompt }],
    max_tokens: 200,
  }),
});

const body = await response.json();
if (body.ok) {
  console.log(body.content, body.billing.amountRial);
}

Python

import os, requests

response = requests.post(
    "https://melliapi.net/api/v1/ai/chat/completions/",
    headers={"Authorization": f"Bearer {os.environ['MELLIAPI_API_KEY']}"},
    json={
        "model": "gemini-flash",
        "messages": [{"role": "user", "content": prompt}],
        "max_tokens": 200,
    },
    timeout=120,
)
body = response.json()
if body.get("ok"):
    print(body["content"], body["billing"]["amountRial"])

PHP / وردپرس

$response = wp_remote_post( 'https://melliapi.net/api/v1/ai/chat/completions/', array(
    'timeout' => 120,
    'headers' => array(
        'Authorization' => 'Bearer ' . MELLIAPI_API_KEY,
        'Content-Type'  => 'application/json',
    ),
    'body' => wp_json_encode( array(
        'model'      => 'gemini-flash',
        'messages'   => array( array( 'role' => 'user', 'content' => $prompt ) ),
        'max_tokens' => 200,
    ) ),
) );

if ( is_wp_error( $response ) ) {
    return; // شبکه قطع بود، دوباره تلاش کنید.
}

$body = json_decode( wp_remote_retrieve_body( $response ), true );
if ( ! empty( $body['ok'] ) ) {
    // $body['content'] پاسخ مدل است.
}

⚠️ مهلت (timeout) را دست‌کم ۱۲۰ ثانیه بگذارید. پاسخ‌های بلند زمان می‌برند و مهلت کوتاه یعنی شما پاسخ را نمی‌بینید در حالی که صورتحسابش صادر شده.

آنچه نگه نمی‌داریم

متن پیام‌ها و پاسخ مدل ذخیره نمی‌شود. از هر فراخوان فقط نام مدل، وضعیت، شمار توکن، مبلغ و زمان ثبت می‌شود، همان چیزی که در بخش هوش مصنوعی پنل می‌بینید.