کلیدهای API

REST API عمومی برای چت، تصویر، صدا، موزیک و ویدیو — با کلید API و موجودی الماس.

شروع سریع (۶۰ ثانیه)

سه قدم تا اولین فراخوانی API:

  1. در داشبورد → API یک کلید بسازید و کلید سکرت آن را که فقط یک‌بار نمایش داده می‌شود کپی کنید.
  2. کلید سکرت را در متغیر محیطی ذخیره کنید: export BINOBOX_API_KEY="binox_sk_live_..."
  3. با GET /models تست کنید — اگر JSON برگشت داد، کلید فعال است.
# 1. Create a key in Dashboard → API, copy the secret (shown once)
export BINOBOX_API_KEY="binox_sk_live_..."

# 2. Confirm auth works
curl -sS https://api.binobox.ir/api/v1/models \
  -H "Authorization: Bearer $BINOBOX_API_KEY"

# 3. First chat call
curl -sS https://api.binobox.ir/api/v1/chat/completions \
  -H "Authorization: Bearer $BINOBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gemini-3.1-flash-lite","messages":[{"role":"user","content":"hi"}]}'

آدرس پایه

پیشوند همهٔ مسیرها:

https://api.binobox.ir/api/v1GET /models

از binobox.ir/api/v1 استفاده نکنید — فقط api.binobox.ir (یا همان آدرسی که در .env سرور دارید).

احراز هویت

در هر درخواست هدر Authorization را بگذارید. YOUR_API_KEY را با کلید کامل binox_sk_live_… جایگزین کنید.

Authorization: Bearer YOUR_API_KEY

برای POSTهای JSON هدر Content-Type: application/json لازم است.

کلید را در گیت یا فرانت‌اند عمومی قرار ندهید — فقط روی سرور خود نگه دارید.

الماس و هزینه

همان موجودی الماس داشبورد. قبل از اجرا موجودی چک می‌شود؛ بعد از موفقیت الماس کسر می‌شود. در پاسخ‌های موفق فیلد binobox را ببینید.

فیلد binobox در پاسخ

در پاسخ‌های موفق (چت، تصویر، صدا، …) این شیء برگردانده می‌شود:

"binobox": {
  "diamonds_charged": 0.18,
  "balance_remaining": 970.34
}

جدول endpointها

متدمسیرScopeتوضیح
GET/modelsلیست مدل‌های مجاز برای scope کلید + حداقل هزینه الماس
GET/usageآمار ۳۰ روز اخیر همین کلید + موجودی فعلی
POST/chat/completionschatچت متنی — بدنه شبیه OpenAI (model + messages)
POST/images/generationsimageتولید تصویر — prompt + settings؛ خروجی base64
POST/audio/speechaudioTTS — فیلد input به‌جای prompt
POST/audio/musicmusicتولید موزیک — prompt + duration در settings
POST/videos/generationsvideoشروع job ویدیو — غیرهمزمان؛ برمی‌گرداند id، poll_url و status
GET/jobs/:idvideoوضعیت job غیرهمزمان (ویدیو و …) — مالکیت و scope الزامی

مصرف و آمار (GET /usage)

بدون scope خاص؛ فقط با کلید معتبر:

  • request_count — تعداد کل درخواست‌های ثبت‌شده با این کلید
  • success_count / error_count — موفق و ناموفق
  • diamonds_charged — مجموع الماس کسرشده + balance_remaining موجودی لحظه‌ای

محدوده دسترسی (Scope)

هنگام ساخت کلید فقط chat / image / audio / music / video لازم را فعال کنید. مدل باید در GET /models باشد و capability با scope بخواند.

شیء settings (رسانه)

در تصویر/صدا/موزیک/ویدیو فیلد اختیاری settings همان پارامترهای استودیو است: numberOfImages، duration (ثانیه)، voice، aspectRatio و … بسته به مدل.

ویدیو (غیرهمزمان)

POST /videos/generations بلافاصله job می‌سازد (status: pending) و poll_url برمی‌گرداند. هر ۵–۱۰ ثانیه GET /jobs/:id را صدا بزنید تا status به completed یا failed برسد. الماس پس از اتمام موفق کسر می‌شود. job دیگران همیشه 404 برمی‌گرداند.

Polling در JavaScript

برای کارهای ناهمگام مثل ویدیو با backoff نمایی polling کنید:

// Poll an async job (video / image / audio / music) with exponential backoff.
// Pass the id from POST /videos/generations.
async function pollJob(jobId, apiKey, { maxAttempts = 60 } = {}) {
  let delayMs = 2000;
  for (let i = 0; i < maxAttempts; i++) {
    const res = await fetch("https://api.binobox.ir/api/v1/jobs/" + jobId, {
      headers: { Authorization: "Bearer " + apiKey },
    });
    if (res.status === 429) {
      const retry = Number(res.headers.get("Retry-After")) || 5;
      await new Promise(r => setTimeout(r, retry * 1000));
      continue;
    }
    if (!res.ok) throw new Error("Job poll failed: " + res.status);
    const job = await res.json();
    if (job.status === "completed") return job;
    if (job.status === "failed" || job.status === "cancelled") {
      throw new Error(job.error?.message || "Job failed");
    }
    await new Promise(r => setTimeout(r, delayMs));
    delayMs = Math.min(delayMs * 1.5, 15_000);
  }
  throw new Error("Job timed out");
}

محدودیت نرخ

پیش‌فرض حدود ۶۰ درخواست در دقیقه به ازای هر کلید (429). برای ویدیو تعداد jobهای pending هم محدود است.

نمونه درخواست و پاسخ

YOUR_API_KEY را عوض کنید. model را از GET /models بردارید.

GET /modelsلیست مدل‌ها

قبل از هر درخواست مدل و capability مجاز را ببینید.

درخواست (curl)

curl -sS https://api.binobox.ir/api/v1/models \
  -H "Authorization: Bearer YOUR_API_KEY"

نمونه پاسخ

{
  "object": "list",
  "data": [
    {
      "id": "gemini-3.1-flash-lite",
      "object": "model",
      "owned_by": "Google",
      "capabilities": ["chat"],
      "min_cost_diamonds": 0.18
    }
  ]
}
GET /usageمصرف کلید

مانیتورینگ هزینه و تعداد درخواست ۳۰ روز اخیر.

درخواست (curl)

curl -sS https://api.binobox.ir/api/v1/usage \
  -H "Authorization: Bearer YOUR_API_KEY"

نمونه پاسخ

{
  "object": "usage",
  "period_days": 30,
  "request_count": 42,
  "success_count": 40,
  "error_count": 2,
  "diamonds_charged": 15.5,
  "balance_remaining": 970.34
}
POST /chat/completionsچت

settings.apiDocsEx_chat_desc

درخواست (curl)

curl -sS https://api.binobox.ir/api/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.1-flash-lite",
    "messages": [{"role": "user", "content": "سلام"}],
    "max_tokens": 256,
    "temperature": 0.7
  }'

نمونه پاسخ

{
  "id": "chatcmpl-…",
  "object": "chat.completion",
  "model": "gemini-3.1-flash-lite",
  "choices": [{
    "message": { "role": "assistant", "content": "سلام!" },
    "finish_reason": "stop"
  }],
  "usage": { "total_tokens": 12 },
  "binobox": {
    "diamonds_charged": 0.18,
    "balance_remaining": 970.16
  }
}
POST /images/generationsتصویر

فیلدهای اجباری: model، prompt. خروجی data[].b64_json.

درخواست (curl)

curl -sS https://api.binobox.ir/api/v1/images/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "imagen-4-fast-generate",
    "prompt": "A minimal logo for a tech startup",
    "settings": { "numberOfImages": 1 }
  }'

نمونه پاسخ

{
  "created": 1780350000,
  "data": [{ "b64_json": "<base64>", "mime_type": "image/png" }],
  "binobox": { "diamonds_charged": 20, "balance_remaining": 950.16 }
}
POST /audio/speechگفتار (TTS)

فیلدهای اجباری: model، input (متن). خروجی صوت base64.

درخواست (curl)

curl -sS https://api.binobox.ir/api/v1/audio/speech \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.1-flash-tts",
    "input": "سلام، این یک تست است.",
    "settings": { "voice": "default" }
  }'

نمونه پاسخ

{
  "object": "audio.speech",
  "model": "gemini-3.1-flash-tts",
  "data": [{ "b64_json": "<base64>", "mime_type": "audio/mpeg" }],
  "binobox": { "diamonds_charged": 8, "balance_remaining": 942.16 }
}
POST /audio/musicموزیک

فیلدهای اجباری: model، prompt. duration در settings.

درخواست (curl)

curl -sS https://api.binobox.ir/api/v1/audio/music \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "lyria-3-clip",
    "prompt": "Calm ambient background music, 30 seconds",
    "settings": { "duration": 30 }
  }'

نمونه پاسخ

{
  "object": "audio.music",
  "model": "lyria-3-clip",
  "duration": 30,
  "data": [{ "b64_json": "<base64>", "mime_type": "audio/mpeg" }],
  "binobox": { "diamonds_charged": 60, "balance_remaining": 882.16 }
}
POST /videos/generationsویدیو

job غیرهمزمان — id و poll_url را ذخیره کنید؛ estimated_cost_diamonds برآورد اولیه است.

درخواست (curl)

curl -sS https://api.binobox.ir/api/v1/videos/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "veo-3-lite-generate",
    "prompt": "A cat walking in a sunny garden",
    "settings": { "duration": 4 }
  }'

نمونه پاسخ

{
  "object": "video.generation",
  "id": "job-uuid",
  "status": "pending",
  "model": "veo-3-lite-generate",
  "estimated_cost_diamonds": 800,
  "poll_url": "/api/v1/jobs/job-uuid",
  "binobox": { "diamonds_charged": 0, "balance_remaining": 882.16 }
}
GET /jobs/:idوضعیت job (polling)

بعد از POST ویدیو، poll_url را با همان کلید صدا بزنید تا خروجی یا خطا را بگیرید.

درخواست (curl)

curl -sS https://api.binobox.ir/api/v1/jobs/JOB_ID \
  -H "Authorization: Bearer YOUR_API_KEY"

نمونه پاسخ

{
  "object": "job",
  "id": "job-uuid",
  "type": "video",
  "status": "completed",
  "model": "veo-3-lite-generate",
  "provider": "google",
  "estimated_cost_diamonds": 800,
  "charged_cost_diamonds": 800,
  "refunded_cost_diamonds": null,
  "output": {
    "url": "https://api.binobox.ir/uploads/private/video/2026-06-02/abc.mp4",
    "signed_url": "https://api.binobox.ir/uploads/private/video/2026-06-02/abc.mp4?e=…&s=…",
    "mime_type": "video/mp4",
    "size_bytes": 1843200,
    "duration_seconds": 5
  },
  "error": null,
  "created_at": "2026-06-02T10:00:00.000Z",
  "started_at": "2026-06-02T10:00:01.000Z",
  "completed_at": "2026-06-02T10:00:45.000Z"
}

خطاها

بدنهٔ خطا معمولاً این شکل است:

{
  "error": {
    "message": "Insufficient diamonds",
    "type": "api_error",
    "code": "INSUFFICIENT_DIAMONDS",
    "required": 800,
    "balance": 12.5
  }
}
  • 401 — کلید نامعتبر، حذف‌شده یا ارسال نشده
  • 402 — الماس کافی نیست (INSUFFICIENT_BALANCE)
  • 403 — scope یا مدل مجاز نیست
  • 400 — پارامتر ناقص (مثلاً model / prompt / messages)
  • 404 — job پیدا نشد یا متعلق به شما نیست (JOB_NOT_FOUND)
  • 429 — محدودیت درخواست در دقیقه
  • 429 — تعداد job ویدیوی در صف زیاد (VIDEO_JOB_LIMIT)
  • 502 — خطای سرویس‌دهندهٔ مدل (PROVIDER_ERROR)
  • 503 — API عمومی روی سرور غیرفعال است

بهترین شیوه‌ها

  • کلید سکرت را در متغیر محیطی بگذارید — هرگز در سورس‌کد یا گیت کامیت نکنید.
  • برای خطاهای ۵۰۲/۵۰۳/۵۰۴ با backoff نمایی retry کنید (۱s، ۲s، ۴s، ۸s).
  • روی ۴۲۹ صبر کنید و هدر Retry-After را بخوانید — این مقدار به ثانیه است.
  • اگر کلیدی لو رفت، فوراً در داشبورد → API لغو کنید. کلیدها بعد از لغو دیگر authenticate نمی‌شوند.
  • کمترین scope ممکن را بدهید — کلید chat-only نمی‌تواند job گران‌قیمت ویدیو بسازد.

برای ساخت کلید وارد حساب شوید: کلیدهای API