Functions API
Deploy and invoke serverless functions.
Deploy and invoke serverless functions.
These endpoints cover standard functions only. Durable functions are a separate collection under /projects/{projectId}/durable-functions, and a durable function's id answers 404 here.
List Functions
GET /projects/{projectId}/functions
Authorization: Bearer <platform_token>Query Parameters:
page,limit- Pagination
Response:
{
"data": [
{
"id": "func-uuid",
"name": "my-function",
"status": "active",
"is_public": false,
"invocation_mode": "rpc",
"http_auth_mode": "volcano",
"openapi_spec": null,
"invoke_url": "https://func-uuid.functions.staging.volcano.run/",
"deployed_regions": ["us-east-1", "us-west-2"],
"runtime": "nodejs24.x",
"handler": "index.handler",
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z"
}
]
}Get Function
GET /projects/{projectId}/functions/{functionId}
Authorization: Bearer <platform_token>The response is a Function resource and includes invoke_url, created_at, and updated_at when available.
Create or Update Function Code
POST /projects/{projectId}/functions
Authorization: Bearer <platform_token>
Content-Type: multipart/form-dataRequest:
curl -X POST "https://api.volcano.dev/projects/$PROJECT_ID/functions" \
-H "Authorization: Bearer $PLATFORM_TOKEN" \
-F "name=my-function" \
-F "runtime=nodejs24.x" \
-F "handler=handler" \
-F "code=@function.zip"Parameters:
name(required) - DNS-safe function name (max 63 characters, lowercase letters/numbers/hyphens, cannot start or end with hyphen)code(required) - ZIP ortar.gzarchive containing function source code plus dependency manifests/lockfilesruntime(required) - Runtime environmenthandler(optional) - Function name to invoke; defaults tohandleris_public(optional) - Function visibility; defaults tofalsefor a new functioninvocation_mode(optional) -rpc(default) orhttphttp_auth_mode(optional) -volcano(default) ornone;nonerequires a public HTTP functionopenapi_spec(optional) - JSON-encoded OpenAPI 3.0 or 3.1 document for HTTP-mode metadata
Cloud deploys install Node.js, Python, and Ruby dependencies during the function compile build. Upload source and manifests such as package.json, requirements.txt, or Gemfile; do not upload installed dependency directories such as node_modules, python_deps, .venv, or vendor.
Python dependencies are staged outside application source and exposed to the
build through PYTHONPATH and PATH. The build command therefore does not see
installed packages copied into its source tree, and application source wins
publish-time file collisions.
The top-level path .volcano-dependencies is reserved for dependency staging.
An uploaded function containing that path is accepted asynchronously, then its
compile build fails with a reserved-path validation error.
Direct API clients may upload ZIP or tar.gz; the API stores a normalized tar.gz source archive. Uploaded source archives cannot contain symlink entries. The API enforces SOURCE_ARCHIVE_SIZE_LIMIT_MB on uploaded and normalized source archives. The CLI uploads tar.gz and does not enforce its own source archive size limit.
After dependencies are installed and the final image is built, the publish build rejects images larger than LAMBDA_TARGET_CONTAINER_SIZE_LIMIT_MB.
For direct API uploads, Volcano generates .volcano/function-build.json automatically. It infers function_root from the single runtime entry file (index.js/index.mjs, main.py, or main.rb), or from the only top-level directory when the archive has one. It infers install_root from the closest dependency manifest directory that contains the function root, otherwise it uses the function root.
Runtimes:
nodejs22.x,nodejs24.xpython3.10,python3.11,python3.12,python3.13,python3.14ruby3.3,ruby3.4,ruby4.0
Response: 201 Created
If a function with the same name already exists, the same endpoint updates that
function's runtime, handler, and source bundle and returns 200 OK.
Deployment and code update are asynchronous. A deployment that starts
immediately returns status: provisioning, then transitions to active or
failed. If another deployment is running, the function keeps its current
status and exposes the queued deployment as pending_deployment_id.
For an existing function, the last known-good runtime continues serving traffic while the update provisions. A failed update leaves that runtime available and records the attempted deployment as failed.
Only one deployment runs for a given function. A newer deploy is accepted and
queued; it supersedes any older queued deploy and starts when the running
deployment finishes. Different functions and projects deploy concurrently.
Deployment history reports waiting work as queued and replaced work as
superseded.
Limit: Each project can contain up to 10,000 standard functions. Creating a new function over this cap returns 403 Forbidden. Durable functions have their own cap of the same size, counted separately.
Deploy Multiple Functions
POST /projects/{projectId}/functions/batch
Authorization: Bearer <platform_token>
Content-Type: multipart/form-dataThe functions multipart field is a JSON array describing each function (name, runtime, optional handler, and file_field). Each file_field points to a multipart file field containing that function's ZIP or tar.gz source bundle. The response includes a shared batch_id and the accepted function resources. Each function still runs its own cloud compile/publish workflow concurrently. The Volcano CLI automatically splits functions deploy --all into multiple 100-function batch requests when needed.
One batch request can include up to 100 functions. Submit multiple batch requests for larger projects.
If one function fails before its workflow starts, the API keeps already-started function deployments running and returns the failure in a failed array. Failed new functions are deleted; failed updates are rolled back to their previous metadata/status where possible.
Batch deploys follow the same source-bundle rules as single-function deploys: upload source and dependency manifests, not installed dependencies.
Invoke Function
RPC functions can be invoked in two ways:
- DNS endpoint (recommended, geo-routed): the function's
invoke_url, which in production readshttps://{functionId}.functions.volcano.run/ - API endpoint (direct invocation):
POST https://api.volcano.dev/functions/{functionId}/invoke
The two live on different domains, and the DNS endpoint differs between
deployments. Send requests to invoke_url as returned rather than building the
host yourself.
POST /functions/{functionId}/invoke
Authorization: Bearer <service_key_or_access_token_or_anon_key>
Content-Type: application/jsonCORS preflight for invocation only allows:
Access-Control-Allow-Methods: POST, OPTIONSHTTP-mode DNS endpoints accept GET, HEAD, POST, PUT, PATCH, and
DELETE on / and nested paths. Their preflight response advertises:
Access-Control-Allow-Methods: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONSDNS equivalent:
POST <invoke_url>
Authorization: Bearer <service_key_or_access_token_or_anon_key>
Content-Type: application/jsonToken behavior:
- Service key: always allowed
- Auth user access token: always allowed
- Anon key: allowed only when both are true:
- key has
functions.invokepermission - function has
is_public: true
- key has
For an HTTP function with http_auth_mode: none, the DNS endpoint does not
require a Volcano token. This mode is valid only with is_public: true and is
intended for webhooks that validate provider signatures inside the function.
The direct /functions/{functionId}/invoke RPC endpoint remains authenticated.
Request:
{
"payload": {
"action": "process",
"data": "value"
}
}With service key:
// Function receives
{
"action": "process",
"data": "value"
}With Auth User Token:
// Function receives
{
"action": "process",
"data": "value",
"__volcano_auth": {
"user_id": "uuid",
"email": "user@example.com",
"project_id": "project-uuid",
"role": "authenticated",
"access_token": "eyJhbGci..."
}
}Response:
{
// Raw function response body
}The HTTP status code and headers are forwarded from the function response, except
for the platform-owned ones (X-Volcano-Version, X-Volcano-Region,
X-Volcano-Health, X-Volcano-Function-Invoked, X-Volcano-Proxy-Ms,
X-Volcano-Proxy-Handler-Ms, X-Volcano-Compute-Ms) and
Volcano's internal headers, which are dropped.
All successful function invocations include X-Volcano-Version (<version> in production, <env>-<version> in non-production environments), X-Volcano-Region, X-Volcano-Proxy-Ms (milliseconds spent preparing the call, from your request arriving until your function ran), X-Volcano-Proxy-Handler-Ms (the part of that spent in the invoke endpoint itself), and X-Volcano-Compute-Ms (milliseconds spent running your function).
The JavaScript, Python, and Ruby SDKs can recover a rejected user credential before dispatch: they refresh the captured session once per resolution or invocation stage and retry with the original payload. They preserve explicit session replacement and never replay a function's own HTTP response, a platform 403, or an ambiguous network failure. See the JavaScript, Python, and Ruby guides for native response and error handling.
Resolve Function Name
Resolves a function name to function ID and invocation URL in the caller's project.
Used by SDKs before DNS invocation. Invoke the returned invoke_url as-is; it is
not derivable from the API host. It is omitted in local development, where you
invoke through POST /functions/{functionId}/invoke instead.
GET /functions/resolve?name={functionName}
Authorization: Bearer <service_key_or_access_token_or_anon_key>Token behavior:
- Service key: allowed
- Auth user access token: allowed
- Anon key: allowed only when:
- key has
functions.invokepermission - function is public (
is_public: true)
- key has
Response:
{
"name": "my-function",
"function_id": "3cd3e058-e3ff-42a5-ae4d-650ef9b45746",
"invoke_url": "https://3cd3e058-e3ff-42a5-ae4d-650ef9b45746.functions.volcano.run/",
"cache_ttl_seconds": 300
}Get Function Logs
POST /projects/{projectId}/logs/search
Authorization: Bearer <platform_token>
Content-Type: application/jsonThese are runtime invocation logs. Set resource.type to function; omit
resource.ids to list logs across all functions or include one or more function
IDs for selected functions. The optional q field runs a free-text search. When
q is omitted or blank, the endpoint returns stored logs using structured
filters only. Use invocation.id in q to select one function invocation.
Deployment build logs use the resource deployment selector below. Authenticate
with the project owner's platform token or a project access token; read_only
is sufficient. Project end-user sessions cannot read these logs.
See the logs guide for query syntax and SDK examples.
Request Body Fields:
resource.type- Required. Usefunctionresource.ids- Optional function IDsq- Optional free-text querylimit- Max events (default: 100, max: 1000)cursor- Opaque pagination cursorstart_time- Inclusive lower bound as an RFC3339 timestampend_time- Inclusive upper bound as an RFC3339 timestamp- Filter levels, regions, and invocation IDs through fields in
q.
Example:
{
"resource": {
"type": "function",
"ids": ["550e8400-e29b-41d4-a716-446655440000"]
},
"q": "body:checkout_failed invocation.id:01JZ8QK9V6X3P5T7N2M4R8C0AB level:(warn OR error) region:us-east-1",
"limit": 50
}Response:
{
"data": [
{
"id": "log/us-east-1/01HKG3W9M0A5V7R2J6Z0Q6Y4S9",
"timestamp": "2024-01-01T12:00:00Z",
"level": "info",
"body": "Log message",
"resource": {
"type": "function",
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "my-function"
},
"region": "us-east-1"
}
],
"limit": 100,
"has_more": true,
"next_cursor": "eyJwayI6..."
}Function Deployment Build Logs
POST /projects/{projectId}/logs/search
Authorization: Bearer <platform_token>Returns runtime and deployment logs through the common project log search API.
For deployment build logs, send resource.type=function,
resource.ids=[functionId], and
resource.deployments.ids=[deploymentId]. The platform token must belong to
the owner of {projectId}.
List Function Deployments
GET /projects/{projectId}/functions/{functionId}/deployments
Authorization: Bearer <platform_token>Returns deployment history for a function, including workflow status and build log metadata.
Delete Function
DELETE /projects/{projectId}/functions/{functionId}
Authorization: Bearer <platform_token>Response: 202 Accepted
Function deletion is asynchronous. If another deployment is running, list/get
responses keep the function's current status and expose the queued deletion as
pending_deployment_id. The status changes to deleting when cleanup starts.
When cleanup finishes, the function no longer appears in lists and
GET /projects/{projectId}/functions/{functionId} returns 404.
Deletion is queued behind a running deployment and supersedes queued deploys.
After deletion is requested, later deploys return 409 Conflict until deletion
finishes.
Update Function Invocation Settings
PATCH /projects/{projectId}/functions/{functionId}
Authorization: Bearer <platform_token>
Content-Type: application/jsonRequest:
{
"is_public": true,
"invocation_mode": "http",
"http_auth_mode": "none",
"openapi_spec": {
"openapi": "3.1.0",
"info": {"title": "Webhook", "version": "1.0.0"},
"paths": {}
}
}is_public: false(default): private function, anon keys cannot invokeis_public: true: public function, anon keys withfunctions.invokecan invokeinvocation_mode: rpc: POST-only{ "payload": ... }contractinvocation_mode: http: HTTP request-event contract on the DNS endpointhttp_auth_mode: volcano: Volcano token authenticationhttp_auth_mode: none: no Volcano token; requiresis_public: trueand HTTP modeopenapi_spec: optional OpenAPI 3.0/3.1 JSON metadata, up to 256 KiB; sendnullto clear
Security note:
is_public: truealone still requires a token. Tokenless access occurs only for the explicithttp+nonecombination. Public functions should always be treated as internet-facing endpoints.
Function Status
provisioning- Being deployedactive- Ready to invokefailed- Deployment failed
Useful deployment fields in responses:
invoke_url- canonical DNS invoke URL for this functiondeployed_regions- regions where the function is currently deployed