Lingara Lingara Dokumentasi Panduan API Pustaka Aplikasi Bina Apl web
Bahasa: Bahasa Melayu

Cipta rancangan pelajaran

Versi API 2026-10-affable-towhee

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

Mula menjana rancangan pelajaran dan menstrim kemajuannya. started menamakan rancangan sebaik sahaja ia wujud, jadi sambungan yang terputus boleh bersambung semula dengan GET /v1/lesson-plans/{id}/stream. Strim berakhir dengan result atau error. Rancangan yang diambil dari pustaka tiba sebagai satu result sahaja.

Skop lesson_plans:write

Parameter

Lingara-Versionheaderstringpilihan
Versi API yang digunakan untuk menjawab permintaan ini. Tanpanya, token akses mendapat versi yang dipautkan kepada kliennya, dan permintaan tanpa token mendapat versi semasa. Versi yang masih dalam pembangunan hanya boleh dicapai dengan menamakannya di sini. Versi yang tidak dikenali dijawab 400 dengan kod api_version_unknown. GET /v1/versions menyenaraikan versi.

Kandungan permintaan application/json

contextstringwajib
source_langstringwajib
target_langstringwajib
levelintegerwajib

Respons

200 Kemajuan rancangan, kemudian rancangan itu

Peristiwa strim text/event-stream

Menghantar komen keepalive setiap 15 saat.

started PlanStarted
plan_idstringwajib
phase PlanPhase
phasestringwajib
attemptintegerwajib
result PlanResult Menamatkan strim
planLessonPlanwajib
idstringwajib
statusPlanStatuswajib
titlestring | nullpilihan
source_langstringwajib
target_langstringwajib
levelintegerwajib
created_atstringwajib
completed_atstring | nullpilihan
ai_generatedbooleanwajib
contentLessonPlanContent | nullpilihan
introductionstring | nullpilihan
learning_objectivesarray of stringwajib
vocabularyarray of PlanWordwajib
wordstringwajib
pronunciationstring | nullpilihan
translationstringwajib
setsarray of PlanSetwajib
numberintegerwajib
contextstring | nullpilihan
questionsarray of PlanQuestionwajib
typestringwajib
promptstringwajib
optionsarray of string | nullpilihan
answerstringwajib
explanationstringwajib
hintstring | nullpilihan
error StreamError Menamatkan strim

Tiba di dalam respons 200. Baris status telah pun dihantar, jadi kegagalan selepas strim dibuka dilaporkan sebagai peristiwa ini.

codestringwajib
messagestringwajib
plan_idstring | nullpilihan

Ralat

402application/json
Panggilan klien bermeter telah ditolak sebelum ia membelanjakan apa-apa. spend_cap_reached: klien atau akaunnya telah mencapai had perbelanjaan bulanannya; naikkan had di halaman Integrasi. metered_billing_inactive: pengebilan bermeter tidak aktif untuk akaun ini; sediakannya, atau kemas kini kaedah pembayaran, di halaman Integrasi.
410application/json
Versi API yang digunakan untuk menjawab permintaan ini telah dihentikan. Hantar versi yang disokong dalam Lingara-Version, atau pautkan klien kepada versi lain.
4XXapplication/json
Permintaan ditolak. code menyatakan sebabnya, dan error menerangkannya dengan perkataan.
503application/json · text/plain
Perkhidmatan tidak tersedia buat sementara waktu; cuba lagi selepas bilangan saat dalam Retry-After. Semasa penyelenggaraan, kandungan ialah teks biasa dan bukan sampul ralat.
5XXapplication/json
Permintaan ditolak. code menyatakan sebabnya, dan error menerangkannya dengan perkataan.
codestringwajib

Sebab permintaan ditolak, sebagai kod stabil untuk dijadikan asas percabangan: contohnya insufficient_scope (403), rate_limited (429) dan, bagi klien bermeter, spend_cap_reached (402) dan metered_billing_inactive (402).

errorstringwajib

Contoh

Bahasa contoh kod

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";
    }
}

Lebih suka pustaka? Lihat bahagian Pustaka.

Contoh strim

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

Jika terjemahan dan rujukan bahasa Inggeris berbeza, rujukan bahasa Inggeris adalah yang betul.