Lingara Lingara Documentation Guides API Bibliothèques Applications Créer Application web
Langue: Français

Créer un plan de leçon

Version de l'API 2026-10-affable-towhee

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

Lance la génération d'un plan de leçon et diffuse sa progression. started identifie le plan dès qu'il existe, afin qu'une connexion interrompue puisse se reconnecter avec GET /v1/lesson-plans/{id}/stream. Le flux se termine par result ou error. Un plan servi depuis la bibliothèque arrive sous la forme d'un unique result.

Portées lesson_plans:write

Paramètres

Lingara-Versionheaderstringfacultatif
La version de l'API sous laquelle traiter cette requête. Sans elle, un jeton d'accès obtient la version à laquelle son client est rattaché, et une requête sans jeton obtient la version actuelle. La version encore en développement ne s'atteint qu'en la nommant ici. Une version inconnue répond 400 avec le code api_version_unknown. GET /v1/versions liste les versions.

Corps de la requête application/json

contextstringobligatoire
source_langstringobligatoire
target_langstringobligatoire
levelintegerobligatoire

Réponses

200 La progression du plan, puis le plan

Événements du flux text/event-stream

Envoie un commentaire keepalive toutes les 15 secondes.

started PlanStarted
plan_idstringobligatoire
phase PlanPhase
phasestringobligatoire
attemptintegerobligatoire
result PlanResult Termine le flux
planLessonPlanobligatoire
idstringobligatoire
statusPlanStatusobligatoire
titlestring | nullfacultatif
source_langstringobligatoire
target_langstringobligatoire
levelintegerobligatoire
created_atstringobligatoire
completed_atstring | nullfacultatif
ai_generatedbooleanobligatoire
contentLessonPlanContent | nullfacultatif
introductionstring | nullfacultatif
learning_objectivesarray of stringobligatoire
vocabularyarray of PlanWordobligatoire
wordstringobligatoire
pronunciationstring | nullfacultatif
translationstringobligatoire
setsarray of PlanSetobligatoire
numberintegerobligatoire
contextstring | nullfacultatif
questionsarray of PlanQuestionobligatoire
typestringobligatoire
promptstringobligatoire
optionsarray of string | nullfacultatif
answerstringobligatoire
explanationstringobligatoire
hintstring | nullfacultatif
error StreamError Termine le flux

Arrive dans la réponse 200. La ligne d'état a déjà été envoyée, donc un échec survenu après l'ouverture du flux est signalé par cet événement.

codestringobligatoire
messagestringobligatoire
plan_idstring | nullfacultatif

Erreurs

402application/json
L'appel d'un client facturé à l'usage a été refusé avant qu'il ne dépense quoi que ce soit. spend_cap_reached : le client ou son compte a atteint sa limite de dépenses mensuelle ; relevez la limite sur la page Intégrations. metered_billing_inactive : la facturation à l'usage n'est pas active pour ce compte ; configurez-la ou mettez à jour le moyen de paiement sur la page Intégrations.
410application/json
La version de l'API sous laquelle cette requête est traitée a été retirée. Envoyez une version prise en charge dans Lingara-Version, ou rattachez le client à une autre version.
4XXapplication/json
La requête a été refusée. code indique pourquoi, et error l'explique en toutes lettres.
503application/json · text/plain
Le service est temporairement indisponible ; réessayez après le nombre de secondes indiqué dans Retry-After. Pendant la maintenance, le corps est du texte brut plutôt que l'enveloppe d'erreur.
5XXapplication/json
La requête a été refusée. code indique pourquoi, et error l'explique en toutes lettres.
codestringobligatoire

Pourquoi la requête a été refusée, sous forme de code stable sur lequel brancher votre logique : par exemple insufficient_scope (403), rate_limited (429) et, pour un client facturé à l'usage, spend_cap_reached (402) et metered_billing_inactive (402).

errorstringobligatoire

Exemple

Langage de l'exemple de code

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

Vous préférez une bibliothèque ? Consultez la section Bibliothèques.

Exemple de flux

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

En cas de divergence entre une traduction et la référence en anglais, la référence en anglais fait foi.