Skip to content

Admin API

The admin API is served on the admin listener (default port 9000). All endpoints are under the /_internal/* prefix.

The ingress listener (default port 8080) handles function invocation at /{function_name}/* and does not expose admin endpoints.

When --api-key is set (or EDGE_RUNTIME_API_KEY), every request to /_internal/* must include the X-API-Key header.

Terminal window
# Rejected (401 Unauthorized)
curl http://localhost:9000/_internal/health
# Accepted (200 OK)
curl -H "X-API-Key: your-secret-key" http://localhost:9000/_internal/health

If --api-key is not set, admin endpoints are open. A warning is logged at startup. This is acceptable for local development but not recommended for production.


Health check. Returns 200 OK when the runtime is operational.

Terminal window
curl http://localhost:9000/_internal/health
{ "status": "ok" }

Returns a JSON object with runtime and per-function metrics. See the Metrics Endpoint reference for the full schema.

Terminal window
curl http://localhost:9000/_internal/metrics

The response is cached for 15 seconds. Use ?fresh=1 to force recomputation.

Terminal window
curl 'http://localhost:9000/_internal/metrics?fresh=1'

Alias for /_internal/metrics. Served on the admin listener. Same caching behavior and ?fresh=1 override.

Terminal window
curl http://localhost:9000/metrics
curl 'http://localhost:9000/metrics?fresh=1'

List all deployed functions.

Terminal window
curl -H "X-API-Key: $KEY" http://localhost:9000/_internal/functions

Response is an array of function info objects including:

FieldTypeDescription
namestringFunction slug
statusstringloading, running, error, shutting_down
bundle_formatstringeszip or snapshot
package_v8_versionstringV8 version in the deployed package
runtime_v8_versionstringV8 version in the current runtime
snapshot_compatible_with_runtimebooleanWhether V8 versions match
requires_snapshot_regenerationbooleantrue when snapshot format and V8 mismatch
created_atstringRFC 3339 timestamp
updated_atstringRFC 3339 timestamp

Deploy a new function. The request body is the bundle payload (ESZIP or snapshot format).

HeaderDescription
x-function-nameName for the deployed function
HeaderDescription
x-function-manifest-b64Base64-encoded function manifest JSON (v2)
x-function-manifest-profileProfile name to resolve from the manifest
x-bundle-signature-ed25519Ed25519 signature (required when --require-bundle-signature is enabled)
Terminal window
curl -X POST \
-H "X-API-Key: $KEY" \
-H "x-function-name: hello" \
--data-binary @hello.eszip \
http://localhost:9000/_internal/functions

Deploy with a manifest:

Terminal window
MANIFEST_B64=$(base64 < function.manifest.json)
curl -X POST \
-H "X-API-Key: $KEY" \
-H "x-function-name: hello" \
-H "x-function-manifest-b64: $MANIFEST_B64" \
--data-binary @hello.eszip \
http://localhost:9000/_internal/functions

If the uploaded bundle contains an embedded manifest (from thunder bundle --manifest), the runtime resolves and applies it when the header is absent.

Manifest validation runs in order:

  1. JSON decode and parse
  2. JSON Schema validation (v2, draft 2020-12)
  3. Semantic checks (flavor/routes rules, SSRF deny range validation)

Returns 400 Bad Request if validation fails.


Get info for a specific deployed function.

Terminal window
curl -H "X-API-Key: $KEY" http://localhost:9000/_internal/functions/hello

Returns the same function info object described in the list endpoint.


Update a deployed function with a new bundle. Same headers as POST /_internal/functions.

Terminal window
curl -X PUT \
-H "X-API-Key: $KEY" \
-H "x-function-name: hello" \
--data-binary @hello-v2.eszip \
http://localhost:9000/_internal/functions/hello

If x-function-manifest-b64 is provided, the manifest is replaced. If omitted, the existing manifest is preserved.


Delete a deployed function and shut down its isolates.

Terminal window
curl -X DELETE \
-H "X-API-Key: $KEY" \
http://localhost:9000/_internal/functions/hello

Hot reload a function. Re-creates isolates from the current bundle without redeploying. The currently attached manifest is preserved.

Terminal window
curl -X POST \
-H "X-API-Key: $KEY" \
http://localhost:9000/_internal/functions/hello/reload

Get per-function isolate pool limits.

Terminal window
curl -H "X-API-Key: $KEY" \
http://localhost:9000/_internal/functions/hello/pool
{
"min": 0,
"max": 10,
"current": 2
}

Update per-function isolate pool limits. Accepts a JSON body with min and/or max fields.

Terminal window
curl -X PUT \
-H "X-API-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{"min": 1, "max": 20}' \
http://localhost:9000/_internal/functions/hello/pool

Inspect the currently attached manifest for a function.

Terminal window
curl -H "X-API-Key: $KEY" \
http://localhost:9000/_internal/functions/hello/manifest
StatusMeaning
200Returns the resolved manifest
404Function exists but has no manifest, or function not found

Function requests are routed through the ingress listener (default port 8080). The function name is extracted from the first path segment, and the remaining path is forwarded to the handler.

GET /my-function/api/users/123
| |
| +-- Forwarded path: /api/users/123
+--------------- Function name: my-function

Requests to /_internal/* on the ingress listener return 404 Not Found.

When using subdomain-style routing in front of the runtime:

External: https://{function_id}.my-edge.com/api/ping
Runtime: http://localhost:8080/{function_id}/api/ping
Admin: http://localhost:9000/_internal/*

MethodPathDescription
GET/_internal/healthHealth check
GET/_internal/metricsRuntime metrics (cached, ?fresh=1 to force)
GET/metricsAlias for /_internal/metrics
GET/_internal/functionsList all functions
POST/_internal/functionsDeploy a new function
GET/_internal/functions/{name}Get function info
PUT/_internal/functions/{name}Update a function
DELETE/_internal/functions/{name}Delete a function
POST/_internal/functions/{name}/reloadHot reload a function
GET/_internal/functions/{name}/poolGet pool limits
PUT/_internal/functions/{name}/poolUpdate pool limits
GET/_internal/functions/{name}/manifestGet attached manifest