تصدير تفاصيل الاستخدام
دليل تصدير استخدام LMU AI: سجّل الدخول للحصول على JWT، ثم استدعِ /api/v1/usage مع الترقيم والنطاق الزمني وتصفية النموذج، مع أمثلة بثلاث لغات.
سجّل الدخول بحسابك وكلمة المرور للحصول على JWT، ثم استخدم هذا الـ JWT لاستدعاء /api/v1/usage وسحب جدول تفاصيل استخدام الرموز الكامل، المطابق لصفحة /usage في وحدة التحكم.
مثالي للسكربتات طويلة الأمد التي تؤتمت التصدير والمطابقة والتحميل إلى أنظمة BI المؤسسية — دون الحاجة إلى تنزيل ملف CSV يدويًا في كل مرة.
لماذا لا يمكنك سحبها مباشرةً باستخدام مفتاح API من نوع sk-...؟ المفتاح مخصص فقط لاستدعاءات أعمال البوابة (/v1/messages، إلخ) ولا يكشف استعلامات التفاصيل على مستوى الحساب — وهذا تصميم أمني متعمّد: إذا تسرّب مفتاح، فأنت لا تريد أن تُكشف فاتورتك بالكامل. يجب أن تستخدم البيانات على مستوى الحساب مصادقة الحساب (JWT).
1. نظرة عامة على الواجهة
| العنصر | القيمة |
|---|---|
| Base URL | https://api.lmuai.com |
| المصادقة | Authorization: Bearer <access_token> (الـ JWT من تسجيل دخول الحساب) |
| صلاحية رمز الوصول | 86400 ثانية (24 ساعة)، قابل للتجديد باستخدام refresh_token |
| تنسيق الاستجابة | JSON؛ code: 0 يعني النجاح، وعند الفشل code != 0 مع حقل message |
| الاستخدام المُوصى به | تصدير الفوترة المؤتمت، التحميل إلى أنظمة BI المؤسسية، سكربتات المطابقة |
2. الخطوة 1 — سجّل الدخول للحصول على JWT
POST /api/v1/auth/login
POST /api/v1/auth/login HTTP/1.1
Content-Type: application/json
{
"email": "your@email.com",
"password": "your-password"
}الاستجابة (مقتطف):
{
"code": 0,
"message": "success",
"data": {
"access_token": "eyJhbGc...",
"refresh_token": "rt_756a220ffa...",
"expires_in": 86400,
"token_type": "Bearer",
"user": { "id": 3, "email": "...", "balance": 1575.13 }
}
}جميع الطلبات اللاحقة تتضمّن فقط Authorization: Bearer <access_token>.
3. الخطوة 2 — اسحب تفاصيل الاستخدام
GET /api/v1/usage
GET /api/v1/usage?page=1&page_size=200&start_date=2026-06-01&end_date=2026-06-23&timezone=Asia/Shanghai
Authorization: Bearer <access_token>معاملات الاستعلام
| المعامل | النوع | مطلوب | الافتراضي | الوصف |
|---|---|---|---|---|
page | int | لا | 1 | رقم الصفحة، يبدأ من 1 |
page_size | int | لا | 20 | عدد الصفوف لكل صفحة، يُوصى بـ 200 (القيم المفرطة تُقتطع) |
start_date | string | لا | — | تاريخ البداية YYYY-MM-DD، يُحلَّل حسب timezone |
end_date | string | لا | — | تاريخ النهاية (شامل ذلك اليوم) |
timezone | string | لا | UTC | المنطقة الزمنية لتحليل معاملات التاريخ، مثل Asia/Shanghai؛ يُوصى بها بشدة، وإلا فلن تتطابق الحدود مع وقتك المحلي |
api_key_id | int | لا | — | عرض تفاصيل مفتاح واحد فقط (يجب أن يكون ملكًا للمستخدم الحالي) |
model | string | لا | — | التصفية حسب معرّف النموذج (مثل claude-sonnet-5) |
stream | bool | لا | — | true للبثّي فقط، false لغير البثّي فقط |
billing_type | int | لا | — | قائمة تعداد نوع الفوترة (انظر أدناه) |
sort_by | string | لا | created_at | حقل الترتيب |
sort_order | string | لا | desc | asc أو desc |
بنية الاستجابة
{
"code": 0,
"message": "success",
"data": {
"items": [ { /* UsageLog */ }, ... ],
"total": 30423,
"page": 1,
"page_size": 200,
"pages": 153
}
}حقول الترقيم موجودة في المستوى الأعلى من data، وليست في الغلاف الخارجي. مصفوفة التفاصيل موجودة في data.items — أي أن data ليست مصفوفة بحدّ ذاتها.
تعيين الحقول لسجل واحد
تقابل هذه بالضبط كل عمود من أعمدة صفحة /usage في وحدة التحكم:
| عمود وحدة التحكم | حقل JSON | النوع | الوصف |
|---|---|---|---|
| النموذج | model | string | معرّف النموذج الذي تمّت فوترته فعليًا |
| جهد الاستدلال | reasoning_effort | string | null | low / medium / high / xhigh / max |
| نقطة النهاية الواردة | inbound_endpoint | string | null | المسار الذي استدعاه العميل، مثل /v1/messages |
| نقطة النهاية العلوية | upstream_endpoint | string | null | المسار العلوي المُطبَّع |
| نوع الطلب | request_type | string | chat / stream / responses / messages، إلخ |
| البثّ | stream | bool | هل كان بثيًا |
| وضع الفوترة | billing_mode | string | token / per_request / image / subscription |
| نوع الفوترة | billing_type | int | قائمة تعداد نوع الفوترة |
| المضاعِف | rate_multiplier | float | مضاعِف القناة المُطبَّق على هذا الطلب |
| رموز الإدخال | input_tokens | int | |
| رموز الإخراج | output_tokens | int | |
| إنشاء الذاكرة المؤقتة | cache_creation_tokens | int | جميع عمليات الكتابة إلى الذاكرة المؤقتة |
| إنشاء الذاكرة المؤقتة 5m | cache_creation_5m_tokens | int | طبقة Anthropic العابرة لمدة 5 دقائق |
| إنشاء الذاكرة المؤقتة 1h | cache_creation_1h_tokens | int | طبقة Anthropic لمدة ساعة واحدة |
| قراءة الذاكرة المؤقتة | cache_read_tokens | int | |
| تكلفة الإدخال | input_cost | float | USD |
| تكلفة الإخراج | output_cost | float | USD |
| تكلفة إنشاء الذاكرة المؤقتة | cache_creation_cost | float | USD |
| تكلفة قراءة الذاكرة المؤقتة | cache_read_cost | float | USD |
| الإجمالي بسعر القائمة | total_cost | float | USD، قبل المضاعِف |
| الرسم الفعلي | actual_cost | float | = total_cost × rate_multiplier، ما يُخصم فعليًا من رصيدك |
| زمن الرمز الأول | first_token_ms | int | null | TTFT، صالح للبثّ |
| المدة الإجمالية | duration_ms | int | null | |
| الوقت | created_at | ISO8601 | وقت الكتابة على جانب الخادم |
| معرّف الطلب | request_id | string | لاستكشاف الأخطاء وتتبعها |
| توليد الصور | image_count / image_size / image_output_tokens / image_output_cost | — | يُملأ فقط للطلبات متعددة الوسائط |
| مفتاح API | api_key_id + كائن api_key المتداخل | int + obj | |
| المجموعة | group_id + كائن group المتداخل | int + obj |
يحمل كل سجل كائنات user / api_key / group متداخلة (حوالي +1KB لكل صف). يحتوي كائن api_key على النص الكامل للمفتاح — احرص على إخفائه في سجلات السكربت / لقطات الشاشة / ملفات CSV؛ وللتصدير بالجملة، إذا لم تكن بحاجة إلى الكائنات المتداخلة، استخدم jq أو تعيين الحقول على جانب العميل للاحتفاظ فقط بالحقول التي تحتاجها.
قائمة تعداد نوع الفوترة (billing_type)
| القيمة | المعنى |
|---|---|
0 | الفوترة بالرمز (الغالبية العظمى من الطلبات) |
1 | خصم من حصة الاشتراك |
حقل billing_mode هو النسخة النصية، ويصف نموذج التسعير المحدد (token / per_request / image / subscription، إلخ)؛ وهو أسهل قراءةً ويُوصى به للتصنيف.
4. تجديد الرمز
تنتهي صلاحية رمز الوصول بعد 24 ساعة. هناك طريقتان لتجديده:
التجديد باستخدام refresh_token (يُوصى به للسكربتات)
POST /api/v1/auth/refresh
Content-Type: application/json
{
"refresh_token": "rt_756a220ffa..."
}يُعيد access_token جديدًا (وعادةً يُدوّر refresh_token أيضًا). صلاحية رمز التحديث 30 يومًا.
تسجيل الدخول مجددًا
طريقة بدائية لكنها بسيطة، مناسبة للسكربتات لمرة واحدة: استدعِ /auth/login مجددًا قبل كل تشغيل.
5. أمثلة برمجية
Bash + curl + jq
#!/usr/bin/env bash
set -e
EMAIL="${EMAIL:?set EMAIL env}"
PASSWORD="${PASSWORD:?set PASSWORD env}"
BASE="https://api.lmuai.com"
JWT=$(curl -s -X POST "$BASE/api/v1/auth/login" \
-H "Content-Type: application/json" \
-d "{\"email\":\"$EMAIL\",\"password\":\"$PASSWORD\"}" \
| jq -r '.data.access_token')
[ -n "$JWT" ] && [ "$JWT" != "null" ] || { echo "login failed" >&2; exit 1; }
START="2026-06-01"; END="2026-06-30"; TZ="Asia/Shanghai"; PAGE_SIZE=200
# Fetch page 1 to get total
META=$(curl -s "$BASE/api/v1/usage?page=1&page_size=$PAGE_SIZE&start_date=$START&end_date=$END&timezone=$TZ" \
-H "Authorization: Bearer $JWT")
PAGES=$(echo "$META" | jq -r '.data.pages')
# CSV header
echo "created_at,model,request_type,input_tokens,output_tokens,cache_read_tokens,total_cost,actual_cost,duration_ms" > usage.csv
# Write page 1
echo "$META" | jq -r '.data.items[] | [.created_at, .model, .request_type, .input_tokens, .output_tokens, .cache_read_tokens, .total_cost, .actual_cost, .duration_ms] | @csv' >> usage.csv
# Fetch remaining pages
for ((p=2; p<=PAGES; p++)); do
curl -s "$BASE/api/v1/usage?page=$p&page_size=$PAGE_SIZE&start_date=$START&end_date=$END&timezone=$TZ" \
-H "Authorization: Bearer $JWT" \
| jq -r '.data.items[] | [.created_at, .model, .request_type, .input_tokens, .output_tokens, .cache_read_tokens, .total_cost, .actual_cost, .duration_ms] | @csv' >> usage.csv
done
echo "saved $(wc -l < usage.csv) lines to usage.csv"Python
import os, csv, requests
BASE = "https://api.lmuai.com"
EMAIL = os.environ["EMAIL"]
PASSWORD = os.environ["PASSWORD"]
def login() -> str:
r = requests.post(f"{BASE}/api/v1/auth/login",
json={"email": EMAIL, "password": PASSWORD},
timeout=15)
r.raise_for_status()
data = r.json()
if data["code"] != 0:
raise RuntimeError(data.get("message", "login failed"))
return data["data"]["access_token"]
def fetch_usage(jwt: str, **params):
"""Yield each row from paginated /usage endpoint."""
page = 1
while True:
r = requests.get(f"{BASE}/api/v1/usage",
headers={"Authorization": f"Bearer {jwt}"},
params={**params, "page": page, "page_size": 200},
timeout=30)
r.raise_for_status()
d = r.json()["data"]
for row in d.get("items", []):
yield row
if page >= d.get("pages", 1):
return
page += 1
if __name__ == "__main__":
jwt = login()
cols = ["created_at","model","request_type","input_tokens","output_tokens",
"cache_read_tokens","total_cost","actual_cost","duration_ms"]
with open("usage.csv", "w", newline="") as f:
w = csv.writer(f); w.writerow(cols)
for row in fetch_usage(jwt, start_date="2026-06-01", end_date="2026-06-30",
timezone="Asia/Shanghai"):
w.writerow([row.get(c) for c in cols])
print("done")Node.js
import fs from 'node:fs'
const BASE = 'https://api.lmuai.com'
const { EMAIL, PASSWORD } = process.env
async function login() {
const r = await fetch(`${BASE}/api/v1/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: EMAIL, password: PASSWORD }),
})
const j = await r.json()
if (j.code !== 0) throw new Error(j.message || 'login failed')
return j.data.access_token
}
async function* fetchUsage(jwt, params) {
for (let page = 1; ; page++) {
const q = new URLSearchParams({ ...params, page, page_size: '200' })
const r = await fetch(`${BASE}/api/v1/usage?${q}`, {
headers: { Authorization: `Bearer ${jwt}` },
})
const j = await r.json()
for (const row of j.data.items) yield row
if (page >= j.data.pages) return
}
}
const jwt = await login()
const cols = ['created_at','model','request_type','input_tokens','output_tokens',
'cache_read_tokens','total_cost','actual_cost','duration_ms']
const out = fs.createWriteStream('usage.csv')
out.write(cols.join(',') + '\n')
for await (const row of fetchUsage(jwt, {
start_date: '2026-06-01', end_date: '2026-06-30', timezone: 'Asia/Shanghai',
})) {
out.write(cols.map(c => JSON.stringify(row[c] ?? '')).join(',') + '\n')
}
console.log('done')6. ملاحظات عملية
- أضف تأخيرًا بين تقليب الصفحات بالجملة — عند تصفح N صفحة على التوالي، يُوصى بـ
sleep(0.1~0.3s)لتجنّب تفعيل حدود المعدل. - لا تسحب نطاقًا زمنيًا طويلًا جدًا دفعة واحدة — امتداد عدة أشهر وملايين الصفوف بطيء. التقطيع حسب الشهر أكثر استقرارًا.
- يُوصى بـ
page_sizeقدره 200 — يقتطع الخادم القيم المفرطة. - وفّر عرض النطاق الترددي — الكائنات المتداخلة
user/api_key/groupكبيرة؛ إذا كنت تريد صفوف التفاصيل فقط، صفّها باستخدامjqعلى جانب العميل. - الأخطاء الشائعة:
401انتهت صلاحية الـ JWT → جدّد باستخدامrefresh_tokenأو سجّل الدخول مجددًا403وصول غير مصرّح به (مثل الاستعلام عن مفتاح شخص آخر عبرapi_key_id) → تحقّق من أن المفتاح يخصّ المستخدم الحالي400معامل خاطئ (مثل تنسيقstart_date) → تحقّق من صحةYYYY-MM-DD+timezone
7. توصيات الأمان (يجب قراءتها)
كلمة مرور حسابك + الـ JWT تعادلان الوصول الكامل إلى الحساب. قبل كتابة سكربت للتصدير، تأكّد من:
| العنصر | التوصية |
|---|---|
| إدارة بيانات الاعتماد | لا تُدرج أبدًا كلمة المرور / access_token / refresh_token في git أو سجلات CI؛ استخدم متغيرات البيئة، أو مدير أسرار، أو .env (مع .gitignore) |
| أمان الحساب | يُوصى بشدة بتفعيل المصادقة الثنائية TOTP (فعّلها في إعدادات الحساب). تدعم هذه الواجهة التحقق عبر TOTP أثناء تسجيل الدخول |
| التدوير الدوري | غيّر كلمة مرور حسابك بانتظام؛ ودوّر refresh_token فورًا بعد انتهاء صلاحيته |
| مراقبة الشذوذ | راقب "آخر وقت / عنوان IP لتسجيل الدخول" في الحساب؛ وغيّر كلمة المرور فورًا إذا لاحظت جهازًا غير مألوف |
| إخفاء الحقول | إن api_key.key المتداخل (نص sk-... الكامل)، وuser.email، وrefresh_token في الاستجابة كلها حقول حساسة — أخفِها قبل الإخراج / السجلات / ملفات CSV |
| أقل امتياز | إن أمكنك الفصل، استخدم حسابًا فرعيًا مخصصًا لسكربت التصدير (إذا كانت لمؤسستك بنية متعددة الحسابات) لتجنّب التعرّض طويل الأمد للحساب الرئيسي |
| إعادة المحاولة عند الأخطاء | لا تُعِد المحاولة إلى ما لا نهاية عند فشل تسجيل الدخول — فهذا يفعّل ضوابط المخاطر بسهولة؛ يُوصى بالتراجع الأسّي |
8. مرجع سريع للحقول
مفيد لتعيين أعمدة CSV:
| التسمية | الحقل | الوحدة |
|---|---|---|
| النموذج | model | — |
| جهد الاستدلال | reasoning_effort | — |
| نقطة النهاية الواردة | inbound_endpoint | path |
| نقطة النهاية العلوية | upstream_endpoint | path |
| نوع الطلب | request_type | enum |
| البثّ | stream | bool |
| وضع الفوترة | billing_mode | enum |
| نوع الفوترة | billing_type | int |
| المضاعِف | rate_multiplier | float |
| رموز الإدخال | input_tokens | int |
| رموز الإخراج | output_tokens | int |
| رموز قراءة الذاكرة المؤقتة | cache_read_tokens | int |
| رموز كتابة الذاكرة المؤقتة | cache_creation_tokens | int |
| كتابة الذاكرة المؤقتة 5m | cache_creation_5m_tokens | int |
| كتابة الذاكرة المؤقتة 1h | cache_creation_1h_tokens | int |
| تكلفة الإدخال | input_cost | USD |
| تكلفة الإخراج | output_cost | USD |
| تكلفة إنشاء الذاكرة المؤقتة | cache_creation_cost | USD |
| تكلفة قراءة الذاكرة المؤقتة | cache_read_cost | USD |
| الإجمالي بسعر القائمة | total_cost | USD |
| الرسم الفعلي | actual_cost | USD |
| الرمز الأول | first_token_ms | ms |
| المدة الإجمالية | duration_ms | ms |
| الوقت | created_at | ISO8601 |
| معرّف الطلب | request_id | string |
| المجموعة | group_id / group.name | int / string |
| مفتاح API | api_key_id / api_key.name | int / string |
آخر تحديث:
احصل على مفتاح API من LMU AI وابدأ باستخدام Claude وCodex والمزيد
تسجيل مجاني وباقات مرنة. مفتاح API واحد لـ Claude Code وCodex CLI وCursor وإضافة VS Code وOpenCode وCherry Studio وغيرها من أدوات الذكاء الاصطناعي.
سجّل الآنGemini Batch Image API
واجهة برمجة الصور الدفعية غير المتزامنة من LMU AI: أرسِل العديد من مهام صور Gemini دفعة واحدة، واستعلم عن الحالة والتفاصيل، ونزّل الصور أو ملف ZIP، مع دعم الـ idempotency وتقديرات التكلفة.
المؤسسات
خطط واجهة برمجة تطبيقات Claude / GPT / Gemini للمؤسسات من LMU AI: 6 وحدات تخزين (Enterprise Standard + Flagship) على Anthropic وOpenAI، مع عقود وفواتير ودعم.