> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cybr.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> These docs cover learner integrations through Hosted Lab Pages, the SDK, and the REST API. Content management is outside this integration scope.
> Read the setup page for the chosen approach before implementing it. Keep organization API keys and hosted mint secrets on the server.
> Install the SDK with `npm install @cybr/labs-sdk`. It runs on the server; the `/terminal`, `/terminal/xterm`, `/video`, and `/hosted-browser` entry points run in the browser.
> Cybr provides completion tracking and CTF verification. The integrating platform decides whether to award points.

# SDK quickstart

> Install the SDK, launch a lab for a learner, and show its connection details.

The SDK is a TypeScript package for your server. It supports ESM and CommonJS imports and includes type definitions.

## Requirements

* An organization account with Cybr Labs
* An organization [API key](/getting-started/api-keys)
* Node.js 22 or later, or another server runtime with a standard `fetch`

## Install the SDK

```bash theme={null}
npm install @cybr/labs-sdk
```

## Create a server client

Read the API key from your server configuration:

```ts theme={null}
import { CybrLabs } from '@cybr/labs-sdk'

const cybr = CybrLabs.init({ key: apiKey })
```

Keep your API key on your server. It can launch labs and read progress for any learner on your platform, so it must never reach the browser: your frontend calls your own backend routes, and those routes use the SDK.

## Launch a lab

1. List the labs available to your organization:

```ts theme={null}
const labs = await cybr.labs.list()
```

2. Resolve the learner ID from your server session. See [learners and membership](/guides/learners-and-membership).
3. Launch the lab:

```ts theme={null}
const deployment = await cybr.deployments.launch({
  labId,
  learnerId,
  membership: 'premium'
})
```

4. Save `deployment.id` with the learner and lab in your database. Later status, terminal, and end requests use that record. See [tracking deployments](/guides/tracking-deployments).
5. Wait for the environment:

```ts theme={null}
const ready = await deployment.waitUntilReady({
  onProgress: (status) => console.log(status.status)
})
```

## Show the connection details

`normalizeOutputs` turns the lab's outputs into rows you can render:

```ts theme={null}
import { normalizeOutputs } from '@cybr/labs-sdk'

const { rows } = normalizeOutputs(ready.outputs)
```

Send these values only to the learner who owns the deployment. The [launch guide](/guides/launching-labs#show-connection-details) explains each field.

## End the lab

When the learner ends the lab, call `destroy()`:

```ts theme={null}
await deployment.destroy()
```

Cybr also ends the environment at its time limit. Ending a lab does not record learner completion.

## Next steps

<CardGroup cols={2}>
  <Card title="Track deployments" icon="database" href="/guides/tracking-deployments">Check ownership, resume after a reload, and avoid duplicate launches.</Card>
  <Card title="Web terminal" icon="terminal" href="/guides/terminals">Give learners a shell in the browser.</Card>
  <Card title="Completion and CTF" icon="flag" href="/guides/completion-and-scoring">Verify flags and record completion.</Card>
  <Card title="Error handling" icon="triangle-exclamation" href="/guides/error-handling">Answer the browser with safe errors.</Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.