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."}]}]}}}

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