Skip to main content
The API cannot list a learner’s deployments, and it accepts any deployment ID in your organization. Your server is the only place that knows which learner owns which deployment, so record each launch.

Store each launch

Add a unique constraint on active rows for each learner and lab. It stops two tabs from launching the same lab at once.

Launch, or resume an active lab

Each launch counts toward your usage and limits. Before launching, look for an active row for the same learner and lab, and return it instead:
The same lookup resumes a running lab after the learner reloads the page.

Check ownership on every request

For status, terminal, and end requests, find the row for the current learner and lab. Use only the deploymentId from that row:
Never act on a deployment ID the browser sends without this check.

End labs

When the learner ends a lab early, for example with an End lab button, call destroy() and close the row:
A not_found, conflict, or deployment_failed error from destroy() means the lab is already over. Close the row in that case too. When lab.timeLimit is set, Cybr ends the lab automatically at launchedAt plus timeLimit minutes. Show a countdown to that time, and close the row when it passes or a status check returns failed.

Failed launches

A timeout or network_error from launch() is ambiguous. The launch may have started a deployment before the connection failed, and the API has no idempotency key. Do not launch again automatically. Ask the learner to wait a minute before trying again. A deployment that did start ends at its time limit. The error guide covers the same rule for other writes.