Skip to content
Hoody.com

Resolve, discover, and test script URL routes; generate, serve, merge, and validate user OpenAPI specs; and manage imported SDK packages. All paths returned by these endpoints are scripts-root-relative (root: /hoody/storage/hoody-exec/scripts) and carry the full `<subdomain>/<execId>` prefix, for example default/1/api/users/[id].ts. The exec service does not apply host or exec scope to routing — pass baseDir explicitly when you need to scope a query to a single exec instance. SDK middleware files generated by the import endpoint are named pre.js and post.js, and marker is the metadata file path default/<sdkId>/.sdk.json.

These endpoints implement Next.js-style dynamic routing against the scripts directory. Routes are matched in priority order: static > dynamic > catch-all > optional catch-all. Every returned script path is scripts-root-relative with the full `<subdomain>/<execId>/` prefix.

Scan the scripts directory and classify each .js or .ts file as static, dynamic ([param]), catch-all ([...slug]), or optional catch-all ([[...path]]). Returns the route pattern, file path (as file), type, and extracted parameter names. Set includeMetadata to include file size and modification time.

This endpoint takes no path, query, or header parameters.

FieldTypeRequiredDescription
baseDirstringNoScripts-root-relative directory to scan. Pass `<subdomain>/<execId>` to scope to a single instance. Default: ""
includeMetadatabooleanNoInclude file size and modification time in each route entry. Default: false
{
"baseDir": "default/1",
"includeMetadata": true
}
{
"baseDir": "default/1",
"count": 2,
"routes": [
{
"file": "default/1/api/users/[id].ts",
"routePattern": "api/users/[id]",
"type": "dynamic",
"parameters": ["id"]
},
{
"file": "default/1/api/posts/[...slug].ts",
"routePattern": "api/posts/[...slug]",
"type": "catchall",
"parameters": ["slug"]
}
]
}
Terminal window
curl -X POST "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/route/discover" \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "Content-Type: application/json" \
-d '{"baseDir": "default/1", "includeMetadata": true}'

Resolve a URL path to the script that handles it, using Next.js-style dynamic routing. Matches in priority order: static > dynamic > catch-all > optional catch-all. Scoped by hostname and execId: checks {hostname}/{execId}/, then {hostname}/, then {execId}/, then root. Returns the matched scriptPath, extracted route parameters, and route type.

This endpoint takes no path, query, or header parameters.

The request body is required but no fields are documented. Send a JSON object — pass any fields the runtime expects (for example, the target path).

{}
{
"matched": true,
"path": "api/users/123",
"scriptPath": "default/1/api/users/[id].ts",
"routePattern": "api/users/[id]",
"parameters": {"id": "123"},
"type": "dynamic",
"baseDir": "default/1"
}

When no route matches, the response still returns 200 with matched: false:

{
"matched": false,
"path": "api/missing",
"hostname": "api.example.com",
"execId": null,
"triedDirectories": ["api.example.com/1/", "api.example.com/", "1/"]
}
Terminal window
curl -X POST "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/route/resolve" \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'

Test multiple URL paths against the routing system in a single batch. For each path, resolves which script would handle it using the same priority and scoping rules as route resolve. Returns per-path match results plus aggregate counts.

This endpoint takes no path, query, or header parameters.

The request body is required but no fields are documented. Send a JSON object containing the batch of paths to test.

{}
{
"tested": 2,
"matched": 1,
"notMatched": 1,
"results": [
{
"path": "api/users/123",
"matched": true,
"scriptPath": "default/1/api/users/[id].ts",
"routePattern": "api/users/[id]",
"parameters": {"id": "123"},
"type": "dynamic",
"baseDir": "default/1"
},
{
"path": "api/missing",
"matched": false,
"triedDirectories": ["1/", ""]
}
]
}
Terminal window
curl -X POST "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/route/test" \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'

Generate, list, validate, serve, and merge OpenAPI specifications derived from your scripts. All paths referenced in these responses are scripts-root-relative with the full `<subdomain>/<execId>/` prefix.

List available scripts with schema information.

NameInTypeRequiredDescription
directoryquerystringNoScript directory to list (absolute or relative to scripts-dir). Default: scripts
dirquerystringNoAlias of directory. Ignored when directory is provided.
subdomainquerystringNoLimit scan to scripts under this subdomain. Falls back to the Host header when omitted.
execIdquerystringNoLimit scan to scripts under this execId. Falls back to the Host header when omitted.
{
"success": true,
"data": {
"directory": "default/1",
"totalScripts": 3,
"withSchemas": 2,
"scripts": [
{
"path": "default/1/api/users/[id].ts",
"routePath": "api/users/[id]",
"hasSchema": true,
"schemaFormat": "zod",
"pathParameters": ["id"]
},
{
"path": "default/1/api/posts.ts",
"routePath": "api/posts",
"hasSchema": true,
"schemaFormat": "json-schema",
"pathParameters": []
},
{
"path": "default/1/api/health.ts",
"routePath": "api/health",
"hasSchema": false,
"pathParameters": []
}
]
}
}
Terminal window
curl "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/user-openapi/list?directory=default/1" \
-H "Authorization: Bearer $HOODY_TOKEN"

Serve a script’s schema file directly. Either file or path must be provided.

NameInTypeRequiredDescription
filequerystringNoAbsolute or scripts-dir-relative path to the target script (for example, default/api/users/[id].ts). Either file or path must be provided.
pathquerystringNoAlias of file. Either file or path must be provided.
{
"zod": {
"input": {
"type": "object",
"properties": {
"id": {"type": "string"}
},
"required": ["id"]
},
"output": {
"type": "object",
"properties": {
"id": {"type": "string"},
"name": {"type": "string"},
"email": {"type": "string", "format": "email"}
},
"required": ["id", "name", "email"]
}
}
}
Terminal window
curl "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/user-openapi/schema?file=default/1/api/users/[id].ts" \
-H "Authorization: Bearer $HOODY_TOKEN"

Generate and serve an OpenAPI specification on-the-fly from the script directory.

NameInTypeRequiredDescription
dirquerystringNoScript directory to scan (absolute or relative to scripts-dir). Default: scripts
directoryquerystringNoAlias of dir. Ignored when dir is provided.
formatquerystringNoOutput format. One of: json, yaml. Default: json
subdomainquerystringNoLimit scan to scripts under this subdomain. Falls back to the Host header when omitted.
execIdquerystringNoLimit scan to scripts under this execId. Falls back to the Host header when omitted.
{
"openapi": "3.0.0",
"info": {
"title": "User API",
"version": "1.0.0"
},
"paths": {
"/api/users/{id}": {
"get": {
"summary": "Get user by id",
"parameters": [
{"name": "id", "in": "path", "required": true, "schema": {"type": "string"}}
],
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"id": {"type": "string"},
"name": {"type": "string"}
}
}
}
}
}
}
}
}
}
}
Terminal window
curl "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/user-openapi/spec?dir=default/1&format=json" \
-H "Authorization: Bearer $HOODY_TOKEN"

Generate an OpenAPI specification from user scripts.

This endpoint takes no path, query, or header parameters.

The request body is required but no fields are documented. Send a JSON object.

{}
{
"success": true,
"data": {
"openapi": "3.0.0",
"info": {"title": "User API", "version": "1.0.0"},
"paths": {}
},
"meta": {
"pathCount": 3,
"scanDirectory": "default/1",
"generatedAt": "2025-01-15T10:30:00.000Z"
}
}
Terminal window
curl -X POST "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/user-openapi/generate" \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'

Merge multiple OpenAPI specs into one.

This endpoint takes no path, query, or header parameters.

The request body is required but no fields are documented. Send a JSON object containing the specs to merge.

{}
{
"success": true,
"data": {
"openapi": "3.0.0",
"info": {"title": "Merged API", "version": "1.0.0"},
"paths": {}
}
}
Terminal window
curl -X POST "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/user-openapi/merge" \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'

Validate a script’s schema file.

This endpoint takes no path, query, or header parameters.

The request body is required but no fields are documented. Send a JSON object identifying the script to validate.

{}
{
"success": true,
"data": {"valid": true, "schemaFormat": "zod"},
"errors": []
}

When validation fails, success is false and errors contains the issues:

{
"success": false,
"data": null,
"errors": [
"Missing required field: output",
"Invalid type at path $.input.id"
]
}
Terminal window
curl -X POST "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/user-openapi/validate" \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'

Import, inspect, list, and delete SDK packages. All SDK paths returned by these endpoints are scripts-root-relative. The SDK root for an imported SDK is default/<sdkId>/; middleware files are default/<sdkId>/pre.js and default/<sdkId>/post.js, and the marker is the metadata file path default/<sdkId>/.sdk.json.

Get the metadata, middleware status, and file inventory for a single SDK.

NameInTypeRequiredDescription
idpathstringYesId parameter
{
"id": "sdk-abc123",
"type": "sdk",
"source_url": "https://github.com/example/sdk.git",
"path": "default/sdk-abc123",
"marker": "default/sdk-abc123/.sdk.json",
"middleware": {
"pre": {
"exists": true,
"path": "default/sdk-abc123/pre.js",
"hash": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
},
"post": {
"exists": false,
"path": null,
"hash": null
}
},
"files": {
"total": 12,
"endpoints": 10,
"list": [
{"path": "default/sdk-abc123/api/users.ts"},
{"path": "default/sdk-abc123/api/posts.ts"}
]
}
}
Terminal window
curl "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/sdk/sdk-abc123" \
-H "Authorization: Bearer $HOODY_TOKEN"

List all imported SDKs.

This endpoint takes no parameters.

{
"sdks": [
{
"id": "sdk-abc123",
"source_url": "https://github.com/example/sdk.git",
"files": 12,
"middleware": {
"pre": true,
"post": false
},
"marker": "default/sdk-abc123/.sdk.json"
}
],
"total": 1
}
Terminal window
curl "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/sdk/list" \
-H "Authorization: Bearer $HOODY_TOKEN"

Import an SDK from a source URL into the scripts directory.

This endpoint takes no path, query, or header parameters.

FieldTypeRequiredDescription
execIdstringYesExec Id
source_urlstringYesSource URL of the SDK to import
source_authstringNoAuthentication token for the source repository
middlewarestringNoMiddleware configuration
magic_commentsstringNoMagic comments to inject into generated scripts
forcebooleanNoForce re-import even if the SDK already exists. Default: false
{
"execId": "1",
"source_url": "https://github.com/example/sdk.git",
"source_auth": "ghp_exampleToken",
"force": false
}
{
"action": "imported",
"summary": {
"new": 12,
"updated": 0,
"conflicts": 0,
"total": 12
},
"sdk": {
"id": "sdk-abc123",
"source_url": "https://github.com/example/sdk.git",
"path": "default/sdk-abc123",
"files": {
"endpoints": 10,
"pre": "default/sdk-abc123/pre.js",
"post": "default/sdk-abc123/post.js",
"marker": "default/sdk-abc123/.sdk.json"
}
}
}
Terminal window
curl -X POST "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/sdk/import" \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"execId": "1",
"source_url": "https://github.com/example/sdk.git"
}'

Delete an SDK and remove all of its files from the scripts directory.

NameInTypeRequiredDescription
idpathstringYesId parameter
{
"message": "SDK deleted",
"removed": {
"marker": "default/sdk-abc123/.sdk.json",
"files": 12,
"directory": "default/sdk-abc123"
}
}
Terminal window
curl -X DELETE "https://67e89abc123def456789abcd-890abcdef12345678901cdef.node-us.containers.hoody.com/api/v1/exec/sdk/sdk-abc123" \
-H "Authorization: Bearer $HOODY_TOKEN"