01 / API PUBLIC CODE ENVIRONMENTS V1

Codelab API

Create coding
environments
from your stack.

Provision a single-language workspace with starter files, then list, update, or delete it over HTTPS. Authenticate with your account API key.

https://usecodelab.com/api/v1

Bearer token on every request

Send your key as an Authorization header. You can also use X-Api-Key. Keys are hashed at rest—only the raw secret works for requests.

Generate or rotate a key in Rails console with user.rotate_api_key!. Store the returned clab_… value immediately; it is not shown again.

REQUEST HEADERAuthorization: Bearer clab_your_secret_here
POST /api/v1/code_environments

One language per environment

Creates an interview workspace for a single language and optional starter files. Multi-language payloads are rejected—open another environment for a second language.

language
Required. One of python, javascript, ruby, java, cpp, c, csharp, go, rust, typescript, php, sql, react.
title
Optional display title.
description
Optional text.
visibility
private (default) or public.
organization_id
Optional org id or uuid. Defaults to your active organization.
code
Optional starter files for that language only. See Code.
curlcurl -X POST https://usecodelab.com/api/v1/code_environments \
  -H "Authorization: Bearer $CODELAB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "language": "python",
    "title": "Two Sum",
    "code": [
      { "filename": "main.py", "content": "def solve():\n    pass\n" },
      { "filename": "README.md", "content": "# Two Sum\n" }
    ]
  }'
GET /api/v1/code_environments

Your environments

Returns up to 100 of your room-root interview environments, newest first. File contents are omitted from the list payload.

RESPONSE{
  "code_environments": [
    {
      "slug": "a1b2c3d4",
      "language": "python",
      "title": "Two Sum",
      "url": "/code/a1b2c3d4",
      "visibility": "private",
      "status": "pending",
      "created_at": "2026-07-24T15:00:00Z",
      "updated_at": "2026-07-24T15:00:00Z"
    }
  ]
}
GET /api/v1/code_environments/:slug

Full environment

Includes starter code for the environment’s language. Other users’ slugs return 404.

curlcurl https://usecodelab.com/api/v1/code_environments/a1b2c3d4 \
  -H "Authorization: Bearer $CODELAB_API_KEY"
PUT /api/v1/code_environments/:slug

Also accepts PATCH.

Metadata and files

Update title, description, visibility, or replace code for the existing language. Changing language is not allowed—create a new environment instead.

curlcurl -X PUT https://usecodelab.com/api/v1/code_environments/a1b2c3d4 \
  -H "Authorization: Bearer $CODELAB_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Two Sum (v2)",
    "code": "def solve():\n    return []\n"
  }'
DELETE /api/v1/code_environments/:slug

Remove a workspace

Deletes the environment and related room children. Responds with 204 No Content on success.

curlcurl -X DELETE https://usecodelab.com/api/v1/code_environments/a1b2c3d4 \
  -H "Authorization: Bearer $CODELAB_API_KEY"

Three shapes, one language

Omit code to seed the default starter for that language. Otherwise pass files as an array, a filename map, or a single string for the default file.

  • Up to 50 files
  • 512 KB per file, 2 MB total
  • No .. or absolute paths in filenames
SHAPES// array
"code": [
  { "filename": "main.py", "content": "print(1)\n" }
]

// filename map
"code": { "main.py": "print(1)\n" }

// single default file
"code": "print(1)\n"

Machine-readable codes

Failures return JSON with error and code. Rate limits include a Retry-After header.

401
unauthorized — missing or invalid API key
404
not_found — unknown or inaccessible slug
402
interview_quota_exceeded — plan or trial limit
422
invalid_code, language_locked, environment_limit_reached, …
429
Rate limited (120 req/min; 20 creates/hour)
ERROR BODY{
  "error": "code may only define the requested language",
  "code": "invalid_code"
}
SHIP WORKSPACES FROM YOUR PIPELINE

Questions about the
API? Say hello.

Contact us ↗