Hoody Code spawns isolated VS Code instances on demand through HTTP requests. You can embed a single extension in your own application, password-protect an environment, and manage several development workspaces from one orchestrator.
Capabilities
Section titled “Capabilities”- Spawn instances - Create a VS Code environment with one HTTP request
- Extension embedding - Open a single already-installed extension in an isolated view
- Password protection - Require a password before an instance is reachable
- Multi-workspace - Independent settings and extensions per instance
- Instance isolation - Separate data directories per instance
- Health monitoring - Track orchestrator status and running instances
- Custom configuration - Pass CLI flags via query parameters
- Instance reuse - Existing instances are reused instead of re-spawned
Two servers, two hostnames
Section titled “Two servers, two hostnames”Hoody Code is two processes, and knowing which one answers a request saves a lot of confusion.
The orchestrator answers on the container’s code URL. It spawns and reuses instances, and that is nearly all it does:
https://PROJECT-CONTAINER-code-1.SERVER.containers.hoody.comEach spawned VS Code instance is its own server on its own port, reached through the container’s HTTP proxy hostname for that port:
https://PROJECT-CONTAINER-http-PORT.SERVER.containers.hoody.comSpawning returns a page whose iframe points at that second hostname. Everything inside the editor, including login and the web key, belongs to the instance rather than the orchestrator.
API Endpoints Summary
Section titled “API Endpoints Summary”On the orchestrator (...-code-1...):
GET /?folder=/path&id=0- Spawn or reuse an instance. Bothfolderandidare required.GET /api/v1/code/health- Orchestrator health checkGET /status- The instances currently running
On a spawned instance (...-http-PORT...):
POST /api/v1/code/mint-key- Generate or retrieve the server’s web key halfGET /login,POST /login,GET /logout- Only when the service was launched in password mode
Basic instance
Section titled “Basic instance”Spawn VS Code for a folder:
# Spawn or reuse instance 0 for a folder. Returns the wrapper HTML page,# whose iframe points at the instance's own hostname.curl "https://PROJECT-CONTAINER-code-1.SERVER.containers.hoody.com/?folder=/home/user/my-project&id=0"
# Check orchestrator healthcurl "https://PROJECT-CONTAINER-code-1.SERVER.containers.hoody.com/api/v1/code/health"# Check orchestrator healthhoody code health -c <container-id>import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://api.hoody.com', token: process.env.HOODY_TOKEN });const containerClient = await client.withContainer({ id: CONTAINER_ID, project_id: PROJECT_ID, server: SERVER });
// Check orchestrator healthconst health = await containerClient.code.health.check();One request, one link
cURL runs inside your container and can wrap any HTTP request into a single GET URL. The call stops being something you need a client for and becomes something you can paste into a browser, send in a chat, bookmark, schedule with cron, or drop into a no-code tool.
Nothing is installed on the machine that opens it. The link does carry whatever credentials the call needs, so treat it as you would treat those credentials.
Slashes, colons and braces pass through as they are. The one character you must
encode is an & inside a value, which happens when the wrapped URL
carries its own query string. Left raw it ends the value early, and the rest is
read as cURL's own parameters, so you get a 200 on a request you did
not make.
How the wrapping works Chaining calls into one link Turning a link into a shortcut
Spawns or reuses instance 0 for the given folder, and checks the orchestrator’s health. Paste either link straight into a browser.
# Spawn
https://PROJECT_ID-CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://PROJECT-CONTAINER-code-1.SERVER.containers.hoody.com/?folder=/home/user/my-project%26id=0&method=GET&response=transparent
# Health
https://PROJECT_ID-CONTAINER_ID-curl-1.SERVER.containers.hoody.com/api/v1/curl/request?url=https://PROJECT-CONTAINER-code-1.SERVER.containers.hoody.com/api/v1/code/health&method=GET&response=transparent Spawning is HTTP only: it is a page request, not an API call, so the CLI and SDK have no equivalent. id is required alongside folder, and omitting it returns a 400.
Extension-only mode
Section titled “Extension-only mode”Add extension to a spawn request and VS Code hides the file explorer, leaving only that extension’s UI. The value is the PUBLISHER.NAME id, so ms-azuretools.vscode-docker works the same way:
# Spawn instance 0 in extension-only modecurl "https://PROJECT-CONTAINER-code-1.SERVER.containers.hoody.com/?folder=/workspace&id=0&extension=ms-python.python"Password protection
Section titled “Password protection”Set password authentication with a CLI flag when the Code service is launched. Login belongs to the spawned instance, not the orchestrator, and lives at the host root:
# Submit login credentials to the instancecurl -X POST "https://PROJECT-CONTAINER-http-PORT.SERVER.containers.hoody.com/login" \ -d 'password=my-password'GET /login returns the form and GET /logout clears the session. All three exist only when the service was launched in password mode.
The mint-key endpoint is separate. It generates or retrieves the server’s 32-byte web key half used for secure communications, and is not a password API. It is also served by the instance:
# Generate/retrieve server web key (binary response)curl -X POST "https://PROJECT-CONTAINER-http-PORT.SERVER.containers.hoody.com/api/v1/code/mint-key"Instance isolation
Section titled “Instance isolation”Each instance keeps its own state:
- Installed extensions live in that instance’s own directory, under
<data-dir>/<id>/extensions - User settings and keybindings are stored separately
- The last opened folder or workspace is saved in settings for the next session
Instance lifecycle
Section titled “Instance lifecycle”First request - Fresh spawn:
- Shows a loading overlay
- Spawns the VS Code process
- Configures it from the request parameters
- Returns the iframe once it is ready
Subsequent requests - Reuse:
- No loading overlay
- Reuses the existing instance rather than re-spawning it
- Keeps the same state
Custom configuration
Section titled “Custom configuration”Use the supported query parameters to configure an instance:
# Spawn instance 0 with the French UI localecurl "https://PROJECT-CONTAINER-code-1.SERVER.containers.hoody.com/?folder=/workspace&id=0&locale=fr"Supported parameters:
folder- What to open. Required. The value is stored in settings for the next session.id- Which instance to spawn or reuse. Required; without it the request is a 400.extension- Open in extension-only mode, given asPUBLISHER.NAMErestart-true,1,yesoronkills the existing instance and spawns a fresh onelocale- Display language, as an IETF language tag such asfr
The orchestrator passes flags through an allowlist. Anything outside it is dropped without an error, so a parameter that looks accepted may simply have been ignored.
Health monitoring
Section titled “Health monitoring”The health check is shown in Basic instance above. Its response:
{ "status": "ok", "service": "hoody-code", "started": "2024-01-15T10:30:00.000Z", "built": "2024-01-10T09:00:00.000Z", "pid": 1234, "ip": "10.0.0.12", "memory": { "rss": 44145050, "heap": 29884416 }, "fds": 42, "userAgent": "HoodyMonitor/1.0"}Use Cases
Section titled “Use Cases”Multi-tenant development
Section titled “Multi-tenant development”Give each user their own instance. Settings and installed extensions stay separate, so one user’s changes do not reach another’s environment.
Embedded development tools
Section titled “Embedded development tools”Embed a single extension in your own application with extension-only mode, which hides the file explorer and leaves just that extension’s UI.
Educational platforms
Section titled “Educational platforms”Run sandboxed coding environments: password-protect student instances, pre-configure extensions, monitor health, and clean up instances between sessions.
CI/CD automation
Section titled “CI/CD automation”Automate code edits by spawning a temporary instance, driving it through extensions, cleaning up when the job finishes, and integrating the whole run with your build pipeline.
Extension showcases
Section titled “Extension showcases”Demonstrate a VS Code extension by embedding an instance in documentation. Readers get an interactive demo of what the extension does and install nothing.
Best Practices
Section titled “Best Practices”Instance strategy
Section titled “Instance strategy”Use a separate folder per project for isolation, and plan capacity for the load you expect.
Folder paths
Section titled “Folder paths”Always use absolute paths such as /home/user/project. Do not use relative paths or .., validate paths to prevent traversal, and make sure the folder exists before spawning.
Password security
Section titled “Password security”Set the password with a CLI flag when launching the Code service, rotate it regularly, and remember that URLs can leak through logs and browser history.
Resource management
Section titled “Resource management”Monitor health via /api/v1/code/health, clean up old instances, and track disk usage in the data directories.
Extension configuration
Section titled “Extension configuration”Validate extension IDs against the PUBLISHER.NAME format, test compatibility before embedding, document system dependencies, and pin versions for consistency.
Useful Questions
Section titled “Useful Questions”Q: How many instances can I run? The practical limit is the container’s memory and CPU.
Q: Do instances persist after restart? Data directories persist, including extensions and settings. Running processes do not, so you re-spawn them.
Q: Can I customize VS Code appearance?
Use the locale query parameter for the display language, load custom CSS/JS via the --external-js/--external-css server flags, and configure further through extension settings.
Q: How do I update extensions? Extensions are installed per instance directory. Update them from the VS Code UI inside the instance, or restart with a fresh data directory.
Q: What happens on first request vs. a reused instance?
A fresh spawn starts a new VS Code process and (when --page-loader is enabled) shows a branded loading overlay during initialization; a reused instance loads its existing process without re-spawning.
Q: Can I run multiple Code services?
Yes. Use different instance numbers such as code-1 and code-2. Each one has its own orchestrator, port range, and data directory.
Q: How do I embed in my app?
Request the URL with the extension parameter, embed the returned page in an iframe, handle authentication if the instance needs it, and monitor the health endpoint.
Troubleshooting
Section titled “Troubleshooting”Instance won’t start
Section titled “Instance won’t start”Cause: Folder not found, invalid parameters.
Solution: Verify the folder exists and is an absolute path, confirm the folder parameter (if used) is passed correctly, and check the orchestrator logs.
Extension not loading
Section titled “Extension not loading”Cause: Invalid extension ID or web-incompatible extension.
Solution: Verify the ID format PUBLISHER.NAME, check that the extension supports the web version, test without extension-only mode first, and confirm the ID on the marketplace.
Password authentication fails
Section titled “Password authentication fails”Cause: Incorrect password or login endpoint misuse. Solution: Verify the password matches the one configured via CLI flag, check the URL encoding of the form body, and confirm the service was started with password authentication enabled.
High resource usage
Section titled “High resource usage”Cause: Too many instances running.
Solution: Check health with /api/v1/code/health, adopt an instance cleanup policy, and increase server resources.
Instance state lost
Section titled “Instance state lost”Cause: Data directory cleared. Solution: Do not delete the data directories of active instances, and back up critical instance data.
Health check fails
Section titled “Health check fails”Cause: Orchestrator down or network issue. Solution: Verify the orchestrator process is running, check network connectivity to the Code Orchestrator URL, and review orchestrator logs for errors.