Code Validation
Section titled “Code Validation”The Code Validation endpoints analyze JavaScript and TypeScript source code submitted to the exec service. Use these endpoints to check syntax, parse TypeScript, verify declared dependencies are installed, validate return-type claims against actual values, and inspect magic comments used to tune script execution.
All endpoints accept a JSON request body and return JSON. They share the same container-scoped base URL and authentication scheme.
https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.comAll requests must carry a bearer token in the Authorization header:
Authorization: Bearer <token>POST /api/v1/exec/validate/dependencies
Section titled “POST /api/v1/exec/validate/dependencies”Inspect the source code for require() and import statements, then compare the referenced modules against the modules installed inside the container. The response reports any missing modules and provides the shell command to install them. A versioned specifier such as lodash@4.17.20 is listed in invalidModules, because require and import refuse it.
This endpoint takes no parameters.
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
code | string | Yes | Source code to scan for dependencies |
{ "code": "import axios from 'axios';\nconst { readFile } = require('fs');\nexport const data = readFile('./input.txt', 'utf8');\nexport default async () => (await axios.get('https://example.com')).data;"}Response
Section titled “Response”{ "totalModules": 4, "allInstalled": false, "missingCount": 2, "missingModules": ["axios", "lodash"], "invalidModules": [], "dependencies": [ { "module": "axios", "status": "missing" }, { "module": "fs", "status": "builtin" }, { "module": "lodash", "status": "missing" }, { "module": "./input.txt", "status": "relative" } ], "message": "Found 2 missing module(s)", "installCommand": "npm install axios lodash"}The request body could not be validated (for example, an empty code field or a body that is not valid JSON).
{ "error": "Missing code in request body", "code": "ERROR_400", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_400 | Bad request | The service answers 400 with this code; the message names the cause. Messages: “Missing code in request body”, “Malformed query string” (Percent-encoding failed to decode. Use valid %XX escapes.), “Invalid JSON body” (Ensure the request body is valid JSON. Example: a backslash followed by a backtick is not a valid JSON escape.), “Request aborted before the body was fully received”. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_408 | Request timeout | The service answers 408 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_413 | Payload too large | The service answers 413 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_429 | Too many requests | The service answers 429 with this code; the message names the cause. Messages: “Too many distinct clients”, “Too many requests”. | — |
{ "error": "Internal server error", "code": "ERROR_500", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_500 | Internal server error | The service answers 500 with this code; the message names the cause. Other messages on this status are composed at runtime and are not listed here. | — |
SDK Usage
Section titled “SDK Usage”import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.exec.scripts.validateDependencies({ code: "import axios from 'axios';\nexport default async () => (await axios.get('https://example.com')).data;"});curl -X POST 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com/api/v1/exec/validate/dependencies' \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json' \ -d '{ "code": "import axios from '"'"'axios'"'"';\nexport default async () => (await axios.get('"'"'https://example.com'"'"')).data;" }'POST /api/v1/exec/validate/magic-comments
Section titled “POST /api/v1/exec/validate/magic-comments”Parse Hoody magic comments (for example, @timeout, @token, @trigger) declared at the top of a script. The response lists each directive, its parsed value, and any warnings produced when a numeric directive could not be interpreted.
This endpoint takes no parameters.
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
code | string | Yes | Source code to scan for magic comments |
{ "code": "// @timeout 30s\n// @token abc123\n// @invalid-value 10x\nexport default async () => 'ok';"}Response
Section titled “Response”{ "magicComments": { "timeout": "30s", "token": "[REDACTED]" }, "warnings": [ { "directive": "@invalid-value", "value": "10x", "message": "Unknown unit suffix 'x'; directive fell back to default" } ], "returnType": { "definition": "string", "mode": "inferred", "location": "10:24" }, "message": "Magic comments parsed"}The request body could not be validated.
{ "error": "Missing code in request body", "code": "ERROR_400", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_400 | Bad request | The service answers 400 with this code; the message names the cause. Messages: “Missing code in request body”, “code must be a string”, “Malformed query string” (Percent-encoding failed to decode. Use valid %XX escapes.), “Invalid JSON body” (Ensure the request body is valid JSON. Example: a backslash followed by a backtick is not a valid JSON escape.), “Request aborted before the body was fully received”. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_408 | Request timeout | The service answers 408 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_413 | Payload too large | The service answers 413 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_429 | Too many requests | The service answers 429 with this code; the message names the cause. Messages: “Too many distinct clients”, “Too many requests”. | — |
{ "error": "Internal server error", "code": "ERROR_500", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_500 | Internal server error | The service answers 500 with this code; the message names the cause. Other messages on this status are composed at runtime and are not listed here. | — |
SDK Usage
Section titled “SDK Usage”import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.exec.magicComments.validate({ code: "// @timeout 30s\n// @token abc123\nexport default async () => 'ok';"});curl -X POST 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com/api/v1/exec/validate/magic-comments' \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json' \ -d '{ "code": "// @timeout 30s\n// @token abc123\nexport default async () => '"'"'ok'"'"';" }'POST /api/v1/exec/validate/return-type
Section titled “POST /api/v1/exec/validate/return-type”Confirm that a JSON value matches a TypeScript-style type definition. Useful for asserting that the runtime payload returned by an executed script conforms to the declared return type.
This endpoint takes no parameters.
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
typeDefinition | string | Yes | A TypeScript-style type declaration (for example, { id: number; name: string }) |
value | any JSON value | Yes | Arbitrary JSON value to validate against the declared return type |
{ "typeDefinition": "{ id: number; name: string; tags: string[] }", "value": { "id": 42, "name": "ada", "tags": ["math", "cs"] }}Response
Section titled “Response”{ "valid": true, "errors": [], "typeDefinition": "{ id: number; name: string; tags: string[] }", "parsedType": { "kind": "object", "properties": { "id": { "kind": "primitive", "type": "number" }, "name": { "kind": "primitive", "type": "string" }, "tags": { "kind": "array", "items": { "kind": "primitive", "type": "string" } } } }, "message": "Value conforms to type"}The request body could not be validated (for example, the value field is not valid JSON or the typeDefinition cannot be parsed).
{ "error": "Missing required fields: typeDefinition and value", "code": "ERROR_400", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_400 | Bad request | The service answers 400 with this code; the message names the cause. Messages: “Missing required fields: typeDefinition and value”, “typeDefinition must be a string”, “Failed to parse type definition”, “Malformed query string” (Percent-encoding failed to decode. Use valid %XX escapes.), “Invalid JSON body” (Ensure the request body is valid JSON. Example: a backslash followed by a backtick is not a valid JSON escape.), “Request aborted before the body was fully received”. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_408 | Request timeout | The service answers 408 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_413 | Payload too large | The service answers 413 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_429 | Too many requests | The service answers 429 with this code; the message names the cause. Messages: “Too many distinct clients”, “Too many requests”. | — |
{ "error": "Internal server error", "code": "ERROR_500", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_500 | Internal server error | The service answers 500 with this code; the message names the cause. Other messages on this status are composed at runtime and are not listed here. | — |
SDK Usage
Section titled “SDK Usage”import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.exec.scripts.validateReturnType({ typeDefinition: '{ id: number; name: string; tags: string[] }', value: { id: 42, name: 'ada', tags: ['math', 'cs'] }});curl -X POST 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com/api/v1/exec/validate/return-type' \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json' \ -d '{ "typeDefinition": "{ id: number; name: string; tags: string[] }", "value": { "id": 42, "name": "ada", "tags": ["math", "cs"] } }'POST /api/v1/exec/validate/script
Section titled “POST /api/v1/exec/validate/script”Run a single script through every available validator in one call: syntax, TypeScript transpile, dependency inspection, magic-comment parsing, and source normalization. The response bundles every result into a single results object together with an overall valid flag.
This endpoint takes no parameters.
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
code | string | Yes | Source code to validate |
language | string | No | Language hint, for example javascript or typescript |
extension | string | No | File extension hint, for example .ts or .mjs |
{ "code": "// @timeout 15s\nimport axios from 'axios';\nexport const handler = async (): Promise<string> => (await axios.get('https://example.com')).status.toString();", "language": "typescript", "extension": ".ts"}Response
Section titled “Response”{ "valid": true, "results": { "syntax": { "valid": true, "message": "JavaScript syntax is valid" }, "typescript": { "valid": true, "transpiledLength": 184 }, "dependencies": { "total": 1, "installed": 0, "missing": 1, "missingModules": ["axios"], "invalidModules": [], "allInstalled": false }, "magicComments": { "timeout": "15s" }, "magicCommentWarnings": [], "normalized": false, "transformations": [] }, "message": "Script validation complete"}The request body could not be validated.
{ "error": "Missing code in request body", "code": "ERROR_400", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_400 | Bad request | The service answers 400 with this code; the message names the cause. Messages: “Missing code in request body”, “code must be a string”, “Malformed query string” (Percent-encoding failed to decode. Use valid %XX escapes.), “Invalid JSON body” (Ensure the request body is valid JSON. Example: a backslash followed by a backtick is not a valid JSON escape.), “Request aborted before the body was fully received”. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_408 | Request timeout | The service answers 408 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_413 | Payload too large | The service answers 413 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_429 | Too many requests | The service answers 429 with this code; the message names the cause. Messages: “Too many distinct clients”, “Too many requests”. | — |
{ "error": "Internal server error", "code": "ERROR_500", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_500 | Internal server error | The service answers 500 with this code; the message names the cause. Other messages on this status are composed at runtime and are not listed here. | — |
SDK Usage
Section titled “SDK Usage”import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.exec.scripts.validate({ code: "// @timeout 15s\nimport axios from 'axios';\nexport const handler = async () => (await axios.get('https://example.com')).status.toString();", language: 'typescript', extension: '.ts'});curl -X POST 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com/api/v1/exec/validate/script' \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json' \ -d '{ "code": "// @timeout 15s\nimport axios from '"'"'axios'"'"';\nexport const handler = async () => (await axios.get('"'"'https://example.com'"'"')).status.toString();", "language": "typescript", "extension": ".ts" }'POST /api/v1/exec/validate/syntax
Section titled “POST /api/v1/exec/validate/syntax”Parse the supplied source code as JavaScript and report whether it is syntactically valid. The response also notes whether the source was normalized before parsing and lists any normalization transformations that were applied.
This endpoint takes no parameters.
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
code | string | Yes | JavaScript source code to parse |
{ "code": "export default function () { return 1 + 1; }"}Response
Section titled “Response”{ "valid": true, "message": "JavaScript syntax is valid", "codeLength": 42, "normalized": false, "transformations": []}The request body could not be validated (for example, the code field is missing or not a string).
{ "error": "Missing code in request body", "code": "ERROR_400", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_400 | Bad request | The service answers 400 with this code; the message names the cause. Messages: “Missing code in request body”, “code must be a string”, “JavaScript syntax error detected”, “Malformed query string” (Percent-encoding failed to decode. Use valid %XX escapes.), “Invalid JSON body” (Ensure the request body is valid JSON. Example: a backslash followed by a backtick is not a valid JSON escape.), “Request aborted before the body was fully received”. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_408 | Request timeout | The service answers 408 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_413 | Payload too large | The service answers 413 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_429 | Too many requests | The service answers 429 with this code; the message names the cause. Messages: “Too many distinct clients”, “Too many requests”. | — |
{ "error": "Internal server error", "code": "ERROR_500", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_500 | Internal server error | The service answers 500 with this code; the message names the cause. Other messages on this status are composed at runtime and are not listed here. | — |
SDK Usage
Section titled “SDK Usage”import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.exec.scripts.validateSyntax({ code: "export default function () { return 1 + 1; }"});curl -X POST 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com/api/v1/exec/validate/syntax' \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json' \ -d '{ "code": "export default function () { return 1 + 1; }" }'POST /api/v1/exec/validate/typescript
Section titled “POST /api/v1/exec/validate/typescript”Transpile TypeScript source to JavaScript and verify the result compiles. Types are stripped and never checked, so typeChecked is always false and a type error is not reported; a syntax error is answered 400. The response contains the transpiled JavaScript output, the byte length of the original and transpiled sources, and the same normalization metadata reported by the syntax endpoint.
This endpoint takes no parameters.
Request Body
Section titled “Request Body”| Name | Type | Required | Description |
|---|---|---|---|
code | string | Yes | TypeScript source code to validate |
{ "code": "interface User { id: number; name: string }\nexport const greet = (u: User): string => `Hello ${u.name}`;"}Response
Section titled “Response”{ "valid": true, "typeChecked": false, "javascript": "export const greet = (u) => `Hello ${u.name}`;\n", "originalLength": 92, "transpiledLength": 54, "normalized": false, "transformations": [], "message": "TypeScript transpiles; types are not checked"}The request body could not be validated.
{ "error": "Missing code in request body", "code": "ERROR_400", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_400 | Bad request | The service answers 400 with this code; the message names the cause. Messages: “Missing code in request body”, “code must be a string”, “TypeScript syntax error”, “Malformed query string” (Percent-encoding failed to decode. Use valid %XX escapes.), “Invalid JSON body” (Ensure the request body is valid JSON. Example: a backslash followed by a backtick is not a valid JSON escape.), “Request aborted before the body was fully received”. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_408 | Request timeout | The service answers 408 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_413 | Payload too large | The service answers 413 with this code; the message names the cause. | — |
| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_429 | Too many requests | The service answers 429 with this code; the message names the cause. Messages: “Too many distinct clients”, “Too many requests”. | — |
{ "error": "TypeScript transpiler not available - requires Bun runtime", "code": "ERROR_500", "timestamp": "2026-01-01T00:00:00.000Z"}| Error Code | Title | Description | Resolution |
|---|---|---|---|
ERROR_500 | Internal server error | The service answers 500 with this code; the message names the cause. Messages: “TypeScript transpiler not available - requires Bun runtime”, “Internal server error”. Other messages on this status are composed at runtime and are not listed here. | — |
SDK Usage
Section titled “SDK Usage”import { HoodyClient } from 'hoody-sdk';
const client = new HoodyClient({ baseURL: 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com', token: process.env.HOODY_TOKEN });
await client.exec.scripts.validateTypes({ code: "interface User { id: number; name: string }\nexport const greet = (u: User): string => `Hello ${u.name}`;"});curl -X POST 'https://{projectId}-{containerId}-exec-1.{server}.containers.hoody.com/api/v1/exec/validate/typescript' \ -H 'Authorization: Bearer <token>' \ -H 'Content-Type: application/json' \ -d '{ "code": "interface User { id: number; name: string }\nexport const greet = (u: User): string => `Hello ${u.name}`;" }'