---
title: "SDK and CLI"
description: "The `landtest` package is not on npm yet. Until it is, call the REST API directly (every example below maps to one documented endpoint) or ask us for early access at contact."
canonical: https://landtest.dev/sdk
last-updated: 2026-10-30
---

# SDK and CLI

## Availability

The `landtest` package is not on npm yet. Until it is, call the REST API directly (every example below maps to one documented endpoint) or ask us for early access at [contact](https://www.landtest.dev/contact).

## CLI

Set `LANDTEST_API_KEY` to a token from Settings, then MCP. Without a key every command runs against the [sandbox](https://www.landtest.dev/sandbox) (`lt_sandbox_demo`).

```
export LANDTEST_API_KEY=lt_mcp_...   # omit to use the sandbox
landtest projects
landtest tests
landtest stats
landtest generate  "Lead the hero with the free trial" --wait
landtest weights  control=50 variant-1=50
landtest api GET /tests//stats
```

## TypeScript client

```
import { Landtest } from "landtest";

const lt = new Landtest({ apiKey: process.env.LANDTEST_API_KEY });

for await (const test of lt.paginate("/projects//tests")) {
  console.log(test.ulid, test.status);
}

const stats = await lt.getTestStats("");
const job = await lt.generateVariant("", { prompt: "Shorter hero" }, { wait: true });
```

- Writes send an `Idempotency-Key` automatically, so retries are safe.
- `429`, `5xx` and network errors retry with backoff, honoring `Retry-After`.
- `paginate()` follows `next_cursor` for you; `generateVariant(..., { wait: true })` polls the job until it finishes.
- Errors throw `LandtestError` with `status`, `code`, `hint` and `requestId`.

## Other languages

Generate a client from the OpenAPI spec at [https://landtest.dev/openapi.json](https://www.landtest.dev/openapi.json), for example with openapi-generator. The base URL is `https://landtest.dev/api/v1`.
