Lingara Lingara Docs Guides API Libraries Apps Build Web app
Language: English

Lingara developer documentation

A connection is made of steps, and any step can carry a script. A step’s script is the body of a function. It receives two values: lingara, the API on this page, and input, the step’s own fields together with its client and the steps joined before it. The type of input depends on the step’s kind, so a webhook step’s script reads a webhook step’s fields. The script returns exactly one object, built by one of the helpers below.

A script never sees a secret. Where a step needs its client, it gets a handle, such as input.client, and the helper records that handle. Lingara fills in the real values when you apply the connection.

What a script must not do

A script runs in your own browser, in a worker with no network and no storage. It is held to these limits:

  • It finishes within 1 second.
  • A string it returns is at most 2048 characters long.
  • A list it returns has at most 64 items.
  • Its whole result is at most 16 KiB.

A script that breaks a limit, throws, or returns something other than one helper’s result fails its step, and “Check it” shows which step and why.

The version promise

Everything on this page is lingara.v1. Within v1 the API only grows: a new helper, a new optional option or a new step kind may appear, but nothing you can use today is removed, renamed or narrowed. A change that would break a script is a new version beside this one, and v1 stays as it is.

The declarations

Each declaration below is generated from the same file the script editor completes against.

NodeHandle

The id of another step, such as "n1". A dependent step names its client by handle.

export type NodeHandle = string;

Scope

A permission an API client may hold. The server judges which ones your account may use.

export type Scope = 'vocab:generate' | 'lesson_plans:read' | 'lesson_plans:write' | 'tutor:converse' | 'usage:read' | 'events:read' | 'events:write' | 'embed:mint' | 'embed:play';

AppSlot

A place in the Lingara app where an app’s card can appear.

export type AppSlot = 'plans.empty_detail' | 'home.side';

ContextSlice

A part of the learner’s context an app may ask to receive.

export type ContextSlice = 'languages' | 'plan_summary' | 'review_due' | 'tutor_topic';

ClientOptions

Options for lingara.client.

export interface ClientOptions {
    name: string;
    scopes: readonly Scope[];
    redirectUris?: readonly string[];
}
  • name (string) — The client’s name, as Developer tools shows it.
  • scopes (readonly Scope[]) — The permissions the client asks for.
  • redirectUris? (readonly string[]) — Where the authorization-code flow may send a learner back to. Omit for a server-to-server client.

WebhookOptions

Options for lingara.webhook.

export interface WebhookOptions {
    client: NodeHandle;
    url: string;
    events: readonly string[];
}
  • client (NodeHandle) — The client step this webhook belongs to: input.client.
  • url (string) — The HTTPS address Lingara delivers events to.
  • events (readonly string[]) — The event types to deliver, such as "lesson_plan.ready".

ManifestOptions

Options for lingara.manifest, in camelCase; the helper writes the manifest’s wire form.

export interface ManifestOptions {
    name: string | Readonly<Record<string, string>>;
    description: string | Readonly<Record<string, string>>;
    renderUrl: string;
    slots: readonly AppSlot[];
    context?: readonly ContextSlice[];
    scopes?: readonly Scope[];
    tutorNote?: boolean;
    defaultLocale?: string;
}
  • name (string | Readonly<Record<string, string>>) — The app’s name: one string, or one string per locale code.
  • description (string | Readonly<Record<string, string>>) — One sentence about the app: one string, or one string per locale code.
  • renderUrl (string) — The HTTPS address Lingara asks for the app’s card.
  • slots (readonly AppSlot[]) — Where the app’s card may appear.
  • context? (readonly ContextSlice[]) — The context slices the app receives. Defaults to none.
  • scopes? (readonly Scope[]) — The permissions the app asks the learner for. Defaults to none.
  • tutorNote? (boolean) — Whether the app may leave a note for the tutor. Defaults to false.
  • defaultLocale? (string) — The locale a plain-string name or description is stored under. Defaults to "en".

AppOptions

Options for lingara.app.

export interface AppOptions {
    client: NodeHandle;
    manifest: Manifest;
}
  • client (NodeHandle) — The client step this app belongs to: input.client.
  • manifest (Manifest) — The app’s manifest, built with lingara.manifest.

ClientSpec

What a client step makes: an API client.

export interface ClientSpec {
    readonly kind: 'client';
    readonly name: string;
    readonly scopes: readonly Scope[];
    readonly redirectUris?: readonly string[];
}
  • kind ('client') — Always "client".
  • name (string) — The client’s name.
  • scopes (readonly Scope[]) — The permissions the client asks for.
  • redirectUris? (readonly string[]) — The client’s redirect URIs, when it has any.

SecretSpec

What a secret step makes: a new secret for its client.

export interface SecretSpec {
    readonly kind: 'secret';
    readonly client: NodeHandle;
}
  • kind ('secret') — Always "secret".
  • client (NodeHandle) — The client step the secret belongs to.

WebhookSpec

What a webhook step makes: a webhook endpoint.

export interface WebhookSpec {
    readonly kind: 'webhook';
    readonly client: NodeHandle;
    readonly url: string;
    readonly events: readonly string[];
}
  • kind ('webhook') — Always "webhook".
  • client (NodeHandle) — The client step the webhook belongs to.
  • url (string) — The address events are delivered to.
  • events (readonly string[]) — The event types delivered.

AppSpec

What an app step makes: an app that renders a card inside Lingara.

export interface AppSpec {
    readonly kind: 'app';
    readonly client: NodeHandle;
    readonly manifest: Manifest;
}
  • kind ('app') — Always "app".
  • client (NodeHandle) — The client step the app belongs to.
  • manifest (Manifest) — The app’s manifest.

Manifest

An app manifest in its wire form, as the server stores it.

export interface Manifest {
    readonly manifest_version: 1;
    readonly default_locale: string;
    readonly name: Readonly<Record<string, string>>;
    readonly description: Readonly<Record<string, string>>;
    readonly render_url: string;
    readonly slots: readonly AppSlot[];
    readonly context: readonly ContextSlice[];
    readonly scopes: readonly Scope[];
    readonly tutor_note: boolean;
}
  • manifest_version (1) — Always 1.
  • default_locale (string) — The locale shown when the learner’s own has no entry.
  • name (Readonly<Record<string, string>>) — The app’s name, per locale code.
  • description (Readonly<Record<string, string>>) — One sentence about the app, per locale code.
  • render_url (string) — The HTTPS address Lingara asks for the app’s card.
  • slots (readonly AppSlot[]) — Where the app’s card may appear.
  • context (readonly ContextSlice[]) — The context slices the app receives.
  • scopes (readonly Scope[]) — The permissions the app asks the learner for.
  • tutor_note (boolean) — Whether the app may leave a note for the tutor.

Spec

Any spec a helper returns. A script returns exactly one.

export type Spec = ClientSpec | SecretSpec | WebhookSpec | AppSpec;

Upstream

Each direct upstream step’s output, by handle.

export type Upstream = Readonly<Record<NodeHandle, Spec & {
    readonly handle: NodeHandle;
}>>;

ClientInput

A client step’s input: its fields, which are lingara.client’s options.

export interface ClientInput {
    readonly name: string;
    readonly scopes: readonly Scope[];
    readonly redirectUris?: readonly string[];
    readonly upstream: Upstream;
}
  • name (string) — The client’s name.
  • scopes (readonly Scope[]) — The permissions the client asks for.
  • redirectUris? (readonly string[]) — The client’s redirect URIs, when the step has any.
  • upstream (Upstream) — Each direct upstream step’s output.

SecretInput

A secret step’s input. client is the one client step joined to this one.

export interface SecretInput {
    readonly client: NodeHandle;
    readonly upstream: Upstream;
}
  • client (NodeHandle) — The client step joined to this one.
  • upstream (Upstream) — Each direct upstream step’s output.

WebhookInput

A webhook step’s input: its fields, plus the joined client.

export interface WebhookInput {
    readonly client: NodeHandle;
    readonly url: string;
    readonly events: readonly string[];
    readonly upstream: Upstream;
}
  • client (NodeHandle) — The client step joined to this one.
  • url (string) — The address the step’s fields name.
  • events (readonly string[]) — The event types the step’s fields name.
  • upstream (Upstream) — Each direct upstream step’s output.

AppInput

An app step’s input: its manifest fields, plus the joined client.

export interface AppInput {
    readonly client: NodeHandle;
    readonly manifest: ManifestOptions;
    readonly upstream: Upstream;
}
  • client (NodeHandle) — The client step joined to this one.
  • manifest (ManifestOptions) — The manifest the step’s fields describe.
  • upstream (Upstream) — Each direct upstream step’s output.

InputFor

The input a script of the given step kind receives.

export type InputFor<K extends Spec['kind']> = K extends 'client' ? ClientInput : K extends 'secret' ? SecretInput : K extends 'webhook' ? WebhookInput : AppInput;

LingaraV1

The helpers a script calls. Each returns a frozen spec, and a wrong-typed option throws a TypeError naming it.

export interface LingaraV1 {
    readonly version: 'v1';
    client(options: ClientOptions): ClientSpec;
    secret(client: NodeHandle): SecretSpec;
    webhook(options: WebhookOptions): WebhookSpec;
    app(options: AppOptions): AppSpec;
    manifest(options: ManifestOptions): Manifest;
}
  • version ('v1') — Always "v1".
  • client(options: ClientOptions): ClientSpec — An API client.
  • secret(client: NodeHandle): SecretSpec — A new secret for a client step.
  • webhook(options: WebhookOptions): WebhookSpec — A webhook endpoint on a client step.
  • app(options: AppOptions): AppSpec — An app on a client step.
  • manifest(options: ManifestOptions): Manifest — A manifest in its wire form, with the options v1 leaves optional filled in.
return lingara.client({ name: input.name, scopes: input.scopes })
return lingara.secret(input.client)
return lingara.webhook({ client: input.client, url: input.url, events: input.events })
return lingara.app({ client: input.client, manifest: lingara.manifest(input.manifest) })

NodeScript

A step’s script is the body of this function: return lingara.webhook({ client: input.client, url: input.url, events: input.events }).

export type NodeScript<K extends Spec['kind']> = (lingara: LingaraV1, input: InputFor<K>) => Spec;

See also