Skip to content
Hoody.com

The Instance Management API lets you stage VS Code extensions from a remote URL and inspect what an instance has staged versus what it appears to have installed. These endpoints are part of the code service that runs inside a Hoody container, and they target it at https://{projectId}-{containerId}-code-1.{server}.containers.hoody.com.

Staging and installing are not the same thing. The editor installs staged extensions only while an instance is starting, so a successful stage reaches a running instance at its next start, not the one that returned the response. The install response reports this as appliesAt and requiresRestartToApply, and the list operation is the only place installation can be confirmed. The stage directory is also shared: an extension staged through one instance is installed by all of them, which the list response reports as desired.scope.

Both operations require an id query parameter naming the instance. There is no discovery branch on these endpoints, so a request that reaches the orchestrator without an id is answered 400 rather than defaulted to a first instance.

Reports the staged set (desired) and what the instance appears to have installed (observed) as two separately labelled sections. They disagree between a stage and the next restart, which is normal and is the point of reporting both.

A section that could not be read is reported as status: "unavailable" with a reason, and its extensions key is omitted entirely rather than returned as an empty list: “no extensions” and “could not look” are different answers, and only one of them is a fault. partial is true whenever either section is in that state, so a client can branch on a single field without inspecting both.

NameInTypeRequiredDescription
idqueryintegerYesWhich instance this request is about. Required here, unlike on GET /api/v1/code: that operation has a discovery branch to fall back to when no selector is given, this one does not, so a request without an id has named no instance and is rejected rather than defaulted to a first one. The value is read exactly as strictly as the selector on GET /api/v1/code: an unsigned decimal integer, under the literal name id only, never given more than once, and at most 65535 - basePort. On a code-N service URL the platform’s edge proxy sets it from the hostname, so callers behind the edge neither send it nor can override it; supply it yourself only when addressing the orchestrator directly.
Terminal window
curl -X GET "https://{projectId}-{containerId}-code-1.{server}.containers.hoody.com/api/v1/code/extensions/list?id=1" \
-H "Authorization: Bearer <token>"

The error body is the shared code_ExtensionError shape, which carries a stable error code and a human-readable message. The error code is the field to branch on; the message is written for a person and may be reworded. The set is closed: a value not in this table did not come from this operation.

Error CodeTitleDescriptionResolution
invalid-requestInvalid requestThe request could not be parsed or failed validationFix the request and resend
invalid-selectorInvalid selectorThe instance selector was unusableSend a valid id query parameter
unknown-instanceUnknown instanceThe named instance does not existUse an id of a known instance
unsupported-media-typeUnsupported media typeThe request body was not application/jsonSend the body as application/json
request-too-largeRequest too largeThe request body exceeded its size limitReduce the size of the request body
destination-refusedDestination refusedThe destination URL is not permitted by the outbound policyUse a URL that satisfies the outbound policy
downgrade-refusedDowngrade refusedThe staged version is newer than the one offered and allowDowngrade was not setSend allowDowngrade: true or stage a newer version
extension-too-largeExtension too largeThe downloaded archive exceeded its size limitStage a smaller extension
not-a-vsixNot a VSIXThe download was not a usable VSIX archiveStage a valid .vsix file
upstream-errorUpstream errorThe far side returned an error responseRetry the request later
upstream-timeoutUpstream timeoutThe download did not finish within the deadlineRetry the request later
installs-at-capacityInstalls at capacityNo install slot was freeWait the number of seconds named in Retry-After and retry
insufficient-storageInsufficient storageThere is not enough space to store the extensionFree space on the stage directory or stage a smaller extension
internal-errorInternal errorThe request could not be completed for a reason on this sideRetry later or contact support

Downloads a .vsix archive from a URL and stages it. The editor installs staged extensions only while an instance is starting, so a successful response means the file is in place and the next start of an instance will attempt to install it, not that any running editor now has it. The response says so in appliesAt and requiresRestartToApply, and GET /api/v1/code/extensions/list is the only place installation can be confirmed.

The URL is fetched under the service’s outbound policy: http and https only, no credentials in the URL, and no address inside the container or on a private network, checked again on every redirect. A refused destination answers 403. A far-side failure answers 502 and may be worth retrying.

NameInTypeRequiredDescription
idqueryintegerYesWhich instance this request is about. Required here, unlike on GET /api/v1/code: that operation has a discovery branch to fall back to when no selector is given, this one does not, so a request without an id has named no instance and is rejected rather than defaulted to a first one. The value is read exactly as strictly as the selector on GET /api/v1/code: an unsigned decimal integer, under the literal name id only, never given more than once, and at most 65535 - basePort. On a code-N service URL the platform’s edge proxy sets it from the hostname, so callers behind the edge neither send it nor can override it; supply it yourself only when addressing the orchestrator directly.
NameTypeRequiredDefaultDescription
urlstringYes—URL of the .vsix to stage. Must be http or https, without credentials in the URL.
allowDowngradebooleanNofalsePermit replacing a staged version with an older one. Refused by default so a routine restage cannot silently roll an extension back.
{
"url": "https://example.com/publisher.name-1.2.3.vsix",
"allowDowngrade": false
}
Terminal window
curl -X POST "https://{projectId}-{containerId}-code-1.{server}.containers.hoody.com/api/v1/code/extensions/install?id=1" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/publisher.name-1.2.3.vsix",
"allowDowngrade": false
}'

The error body is the shared code_ExtensionError shape, which carries a stable error code and a human-readable message. The error code is the field to branch on; the message is written for a person and may be reworded. The set is closed: a value not in this table did not come from this operation.

Error CodeTitleDescriptionResolution
invalid-requestInvalid requestThe request body could not be parsed or failed validationFix the request body and resend
invalid-selectorInvalid selectorThe instance selector was unusableSend a valid id query parameter
unknown-instanceUnknown instanceThe named instance does not existUse an id of a known instance
unsupported-media-typeUnsupported media typeThe request body was not application/jsonSend the body as application/json
request-too-largeRequest too largeThe request body exceeded its size limitReduce the size of the request body
destination-refusedDestination refusedThe destination URL is not permitted by the outbound policyUse a URL that satisfies the outbound policy
downgrade-refusedDowngrade refusedThe staged version is newer than the one offered and allowDowngrade was not setSend allowDowngrade: true or stage a newer version
extension-too-largeExtension too largeThe downloaded archive exceeded its size limitStage a smaller extension
not-a-vsixNot a VSIXThe download was not a usable VSIX archiveStage a valid .vsix file
upstream-errorUpstream errorThe far side returned an error responseRetry the request later
upstream-timeoutUpstream timeoutThe download did not finish within the deadlineRetry the request later
installs-at-capacityInstalls at capacityNo install slot was freeWait the number of seconds named in Retry-After and retry
insufficient-storageInsufficient storageThere is not enough space to store the extensionFree space on the stage directory or stage a smaller extension
internal-errorInternal errorThe stage could not be completed for a reason on this sideRetry later or contact support