> ## 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.
> The public SDK is coming soon. Check the SDK quickstart for current availability. Do not invent installation commands or direct readers to a private package.
> Cybr provides completion tracking and CTF verification. The integrating platform decides whether to award points.

# Learners and membership

> Support signed-in users and guests with stable learner IDs.

## Learner IDs

A `learnerId` identifies a learner in API requests. Cybr does not require that learner to have a Cybr account.

Use these rules for IDs:

* Use an opaque ID from your integration.
* Keep the ID stable for the same learner.
* Add an integration-specific namespace, such as `academy:user:uuid`.
* Keep names and email addresses out of the ID.
* Resolve the ID from a server session.

The namespace prevents accidental collisions with IDs from other integrations. A browser-supplied ID alone does not prove ownership.

## Signed-in learners

The server maps its authenticated session to a stable learner ID. The same ID applies to launches, flags, completion, and discussions.

```ts theme={null}
const deployment = await cybr.deployments.launch({
  labId,
  learnerId: 'academy:user:6c854d0b-639b-45a8-a8d5-61b25f720ac7',
  membership: 'free'
})
```

## Guest learners

The server issues an opaque guest ID and associates it with a guest session. The learner does not require a login.

The session retains its ID across requests. The server stores each deployment ID with the guest session that owns it.

```ts theme={null}
const deployment = await cybr.deployments.launch({
  labId,
  learnerId: 'academy:guest:462b5264-c864-430b-a6c9-3a9d6796f5a3',
  membership: 'free'
})
```

A lost guest session can lose access to its previous deployments and progress. Guest-to-account linking belongs to your platform.

## Membership

Each launch declares `free` or `premium`. The SDK defaults to `free`. Direct REST requests must include the field.

| Membership | Lab access | Default launch limit per five minutes |
| - | - | - |
| `free` | Free labs | 1 |
| `premium` | Free and premium labs | 15 |

These are default launch limits. The API response supplies the current wait time if a request reaches a limit.

Login and membership are independent. Your server chooses membership from your access policy. The browser does not choose premium access.

## Deployment ownership

Before each status, terminal, or end request, check the deployment association in your server session.

The organization key authorizes organization access. It does not replace your checks for individual learners.

## Read completion

```ts theme={null}
const lab = await cybr.labs.get(labId, { learnerId })
console.log(lab.completed)
```

The `learnerId` query scopes the completion result to that learner. Without it, the response does not describe an individual learner.

See [completion and CTF verification](/guides/completion-and-scoring) for recording progress.
