Lingara Lingara مستندات رهنماها API کتابخانه‌ها اپلیکیشن‌ها ساختن اپلیکیشن وب
زبان: دری

ساختن پلان درسی

نسخهٔ API 2026-10-affable-towhee

post https://api.getlingara.com/v1/lesson-plans

ساختن یک پلان درسی را آغاز می‌کند و پیشرفت آن را به صورت جریانی می‌فرستد. started به محض ایجاد پلان، آن را معرفی می‌کند تا اتصال قطع‌شده بتواند با GET /v1/lesson-plans/{id}/stream دوباره وصل شود. جریان با result یا error پایان می‌یابد. پلانی که از کتابخانه ارائه شود، به صورت یک result تنها می‌رسد.

حوزه‌های دسترسی lesson_plans:write

پارامترها

Lingara-Versionheaderstringاختیاری
نسخهٔ API‌ای که این درخواست با آن جواب داده می‌شود. بدون آن، توکن دسترسی نسخه‌ای را می‌گیرد که کلاینت آن به آن وصل است، و درخواستی بدون توکن نسخهٔ فعلی را می‌گیرد. به نسخه‌ای که هنوز در حال انکشاف است تنها با نام‌بردن آن در اینجا می‌توان رسید. نسخهٔ ناشناخته با 400 و کد api_version_unknown جواب داده می‌شود. GET /v1/versions نسخه‌ها را فهرست می‌کند.

بدنهٔ درخواست application/json

contextstringضروری
source_langstringضروری
target_langstringضروری
levelintegerضروری

پاسخ‌ها

200 پیشرفت پلان، سپس خود پلان

رویدادهای جریان text/event-stream

هر 15 ثانیه یک یادداشت keepalive می‌فرستد.

started PlanStarted
plan_idstringضروری
phase PlanPhase
phasestringضروری
attemptintegerضروری
result PlanResult جریان را پایان می‌دهد
planLessonPlanضروری
idstringضروری
statusPlanStatusضروری
titlestring | nullاختیاری
source_langstringضروری
target_langstringضروری
levelintegerضروری
created_atstringضروری
completed_atstring | nullاختیاری
ai_generatedbooleanضروری
contentLessonPlanContent | nullاختیاری
introductionstring | nullاختیاری
learning_objectivesarray of stringضروری
vocabularyarray of PlanWordضروری
wordstringضروری
pronunciationstring | nullاختیاری
translationstringضروری
setsarray of PlanSetضروری
numberintegerضروری
contextstring | nullاختیاری
questionsarray of PlanQuestionضروری
typestringضروری
promptstringضروری
optionsarray of string | nullاختیاری
answerstringضروری
explanationstringضروری
hintstring | nullاختیاری
error StreamError جریان را پایان می‌دهد

در داخل پاسخ 200 می‌رسد. خط وضعیت قبلاً فرستاده شده است، بنابراین هر ناکامی پس از باز شدن جریان به‌عنوان این رویداد گزارش می‌شود.

codestringضروری
messagestringضروری
plan_idstring | nullاختیاری

خطاها

402application/json
فراخوانی یک کلاینت مصرفی پیش از آنکه چیزی مصرف کند رد شد. spend_cap_reached: کلاینت یا حساب آن به سقف مصارف ماهانهٔ خود رسیده است؛ سقف را در صفحهٔ یکپارچه‌سازی‌ها بلند ببرید. metered_billing_inactive: صورت‌حساب مصرفی برای این حساب فعال نیست؛ آن را در صفحهٔ یکپارچه‌سازی‌ها تنظیم کنید یا روش پرداخت را تازه کنید.
410application/json
نسخهٔ API‌ای که این درخواست با آن جواب داده می‌شود متوقف شده است. یک نسخهٔ پشتیبانی‌شده را در Lingara-Version بفرستید، یا کلاینت را به نسخهٔ دیگری وصل کنید.
4XXapplication/json
درخواست رد شد. code دلیل را مشخص می‌کند و error آن را با کلمات بیان می‌کند.
503application/json · text/plain
خدمات به طور موقت در دسترس نیست؛ پس از تعداد ثانیه‌های ذکرشده در Retry-After دوباره کوشش کنید. در زمان ترمیمات، بدنهٔ پاسخ به جای پاکت خطا، متن ساده است.
5XXapplication/json
درخواست رد شد. code دلیل را مشخص می‌کند و error آن را با کلمات بیان می‌کند.
codestringضروری

دلیل رد شدن درخواست، به شکل کدی ثابت که می‌توان بر اساس آن تصمیم گرفت: برای مثال insufficient_scope (403)، rate_limited (429) و، برای یک کلاینت مصرفی، spend_cap_reached (402) و metered_billing_inactive (402).

errorstringضروری

نمونه

زبان نمونهٔ کود

curl

curl -N -X POST "https://api.getlingara.com/v1/lesson-plans" \
  -H "Authorization: Bearer $LINGARA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"context":"Ordering food at a night market","source_lang":"en","target_lang":"zh","level":2}'

TypeScript

const stream = client.createLessonPlan({
  context: "ordering at a night market",
  source_lang: "en",
  target_lang: "zh",
  level: 2,
});
for await (const ev of stream) {
  if (ev.event === "started") console.log("plan", ev.data.plan_id);
  if (ev.event === "phase") console.log("working:", ev.data.phase);
  if (ev.event === "result") console.log(ev.data.plan.title);
}

Rust

use lingara::models::{CreateLessonPlanEvent, LessonPlanCreateRequest};

let request = LessonPlanCreateRequest {
    context: "ordering at a night market".into(),
    source_lang: "en".into(),
    target_lang: "zh".into(),
    level: 2,
};
let mut stream = client.create_lesson_plan(&request).await?;
while let Some(event) = stream.next().await {
    match event? {
        CreateLessonPlanEvent::Started(started) => println!("plan {}", started.plan_id),
        CreateLessonPlanEvent::Phase(phase) => println!("working: {}", phase.phase),
        CreateLessonPlanEvent::Result(result) => println!("{}", result.plan.title.unwrap_or_default()),
        _ => {}
    }
}

Go

s, err := client.CreateLessonPlan(ctx, lingara.LessonPlanCreateRequest{
	Context:    "ordering at a night market",
	SourceLang: "en",
	TargetLang: "zh",
	Level:      2,
})
if err != nil {
	return err
}
defer s.Close()
for ev, err := range s.Events() {
	if err != nil {
		return err
	}
	switch e := ev.(type) {
	case lingara.CreateLessonPlanEventStarted:
		fmt.Println("plan", e.Data.PlanID)
	case lingara.CreateLessonPlanEventPhase:
		fmt.Println("working:", e.Data.Phase)
	case lingara.CreateLessonPlanEventResult:
		if e.Data.Plan.Title != nil {
			fmt.Println(*e.Data.Plan.Title)
		}
	}
}

Java

import com.getlingara.client.model.CreateLessonPlanEvent;
import com.getlingara.client.model.LessonPlanCreateRequest;

LessonPlanCreateRequest request =
    new LessonPlanCreateRequest()
        .context("Ordering at a night market")
        .level(2)
        .sourceLang("en")
        .targetLang("zh");
try (EventStream<CreateLessonPlanEvent> stream = client.createLessonPlan(request)) {
  for (CreateLessonPlanEvent event : stream) {
    if (event instanceof CreateLessonPlanEvent.Started started) {
      // Keep the id: streamLessonPlan rejoins a generation that was cut off.
      System.out.println("plan " + started.data().getPlanId());
    } else if (event instanceof CreateLessonPlanEvent.Phase phase) {
      System.out.println("phase " + phase.data().getPhase());
    } else if (event instanceof CreateLessonPlanEvent.Result result) {
      System.out.println(result.data().getPlan().getTitle());
    }
  }
}

Kotlin

import com.getlingara.kotlin.LingaraClient
import com.getlingara.kotlin.model.CreateLessonPlanEvent
import com.getlingara.kotlin.model.LessonPlanCreateRequest

val request =
    LessonPlanCreateRequest(context = "Ordering at a night market", sourceLang = "en", targetLang = "zh", level = 2)
client.createLessonPlan(request).use { stream ->
    stream.collect { event ->
        when (event) {
            // Keep the id: streamLessonPlan rejoins a generation that was cut off.
            is CreateLessonPlanEvent.Started -> println("plan ${event.data.planId}")
            is CreateLessonPlanEvent.Phase -> println("phase ${event.data.phase}")
            is CreateLessonPlanEvent.Result -> println(event.data.plan.title)
        }
    }
}

Ruby

client.create_lesson_plan(context: "ordering at a night market", source_lang: "en", target_lang: "zh", level: 2) do |event|
  case event
  in Lingara::CreateLessonPlanEventStarted => started then puts "plan #{started.data.plan_id}"
  in Lingara::CreateLessonPlanEventPhase => phase then puts "working: #{phase.data.phase}"
  in Lingara::CreateLessonPlanEventResult => result then puts "ready: #{result.data.plan.title}"
  else nil
  end
end

PHP

use Lingara\Model\LessonPlanCreateRequest;
use Lingara\Stream\CreateLessonPlanEvent;

$request = new LessonPlanCreateRequest([
    'context' => 'ordering at a night market',
    'source_lang' => 'en',
    'target_lang' => 'zh',
    'level' => 2,
]);
foreach ($client->createLessonPlan($request) as $event) {
    if ($event instanceof CreateLessonPlanEvent\Started) {
        echo 'plan ', $event->data->getPlanId(), "\n";
    } elseif ($event instanceof CreateLessonPlanEvent\Phase) {
        echo 'phase: ', $event->data->getPhase(), "\n";
    } elseif ($event instanceof CreateLessonPlanEvent\Result) {
        echo 'ready: ', $event->data->getPlan()->getTitle(), "\n";
    }
}

کتابخانه را ترجیح می‌دهید؟ بخش کتابخانه‌ها را ببینید.

نمونهٔ جریان

event: started
data: {"plan_id":"3f1c2a9e-5b7d-4e21-9a0c-6d8e4f2b1a37"}

event: phase
data: {"phase":"selecting_vocabulary","attempt":1}

event: result
data: {"plan":{"id":"3f1c2a9e-5b7d-4e21-9a0c-6d8e4f2b1a37","status":"complete","title":"At the night market","source_lang":"en","target_lang":"zh","level":2,"created_at":"2026-09-23T10:00:00Z","completed_at":"2026-09-23T10:00:41Z","ai_generated":true,"content":{"introduction":"Order food and ask prices at a night market.","learning_objectives":["Ask how much something costs"],"vocabulary":[{"word":"多少钱","pronunciation":"duōshao qián","translation":"how much"}],"sets":[{"number":1,"questions":[{"type":"multiple_choice_word","prompt":"Which word asks for a price?","options":["多少钱","谢谢"],"answer":"多少钱","explanation":"多少钱 means how much money."}]}]}}}

اگر ترجمه با مرجع انگلیسی فرق داشته باشد، مرجع انگلیسی درست است.