DRAFT — Preliminary version, do not share. · Version préliminaire, ne pas partager.

Runtime and SDK

This page describes the runtime that executes cloud functions: the supported languages and toolchains, what your function reads and writes, how it is triggered, the limits, the SDK, and the execution history. For a step-by-step walkthrough, read the Cloud functions guide.

Runtime model

A cloud function is a WebAssembly module that targets WASI (WebAssembly System Interface). Each invocation runs your module once, in a sandbox:

Aspect Behavior
Input A JSON document on stdin
Output Whatever your function writes to stdout
Logs Whatever your function writes to stderr, kept in the execution history
Configuration Your function's variables, exposed as environment variables
Filesystem None
Network None. Use the SDK host functions to reach Fundamentum
Concurrency One execution at a time per function, unless you configure a worker pool. Extra invocations wait in a queue

Languages and toolchains

Any language that compiles to a WASI module works. These toolchains are known to work:

Language Toolchain Build command
Go Standard Go compiler GOOS=wasip1 GOARCH=wasm go build -o function.wasm .
Go TinyGo See the TinyGo documentation for the wasip1 target
JavaScript Javy javy build function.js -o function.wasm
Python py2wasm py2wasm function.py -o function.wasm
Rust Cargo with a WASI target cargo build --release --target wasm32-wasip1

On macOS, py2wasm does not work with the system Python or the Homebrew Python. Install the official Python build, for example with pyenv.

The language field of a function is descriptive metadata. The runtime executes the WebAssembly module whatever the source language.

Input

Your function receives this JSON document on stdin:

{
  "input": "<base64-encoded bytes>",
  "context": {
    "function_id": "<function-id>",
    "project_id": 1
  },
  "metadata": {
    "<key>": "<base64-encoded bytes>"
  }
}
Field Description
input The payload: the HTTP request body, or the message received on the input topic. Bytes, base64-encoded in the JSON
context.function_id The ID of the function being executed
context.project_id The project the function runs in
metadata Key-value pairs, values base64-encoded. On HTTP invocation, each X-Function-<key> request header becomes a <key> entry

Output

Write the result to stdout. Exit normally on success. If your module exits with an error, the execution is recorded as failed, with your stderr output and the error.

What happens to the output depends on the trigger:

Triggers

Trigger How Input
HTTP POST /v2/projects/{project_id}/functions/{function_id}:invoke on the Public API, or fun functions invoke The request body, sent as application/octet-stream
Topic A connector in fundamentum_iot_connectors: {"input_topic_id": <topic-id>, "output_topic_id": <topic-id>}. output_topic_id is optional Each message received on the input topic

Every function can be invoked over HTTP. Connectors cannot form a cycle: the API rejects a definition whose connectors loop back on themselves. See Topics and Connectors.

The HTTP invocation returns:

{
  "status": "success",
  "data": {
    "started_at": "2026-01-01T12:00:00Z",
    "execution_time": 0.42,
    "output": {
      "format": "json",
      "value": { "processed": 10 }
    }
  }
}

output.format is json when the output is valid JSON, unicode when it is valid UTF-8 text, and base64 otherwise.

Status Meaning
200 The function ran
404 No such function in this project
408 The execution reached its timeout and was stopped
424 The function has no WebAssembly file yet

Function definition

Create and update functions with the v2 functions operations or fun functions new and fun functions edit.

Field Type Description
description string, required Human-readable description
language string, required Source language, for information only
execution_timeout integer, nanoseconds Maximum duration of one execution
keep_alive_timeout integer, nanoseconds How long the compiled function stays loaded after an execution. 0 unloads it right away
fundamentum_iot_connectors array Topic triggers, see above
variables object KEY: value pairs exposed as environment variables
scaling.pool_size integer, greater than 1 Number of workers that execute in parallel

Upload the WebAssembly binary separately, as multipart/form-data with the file in the function field, on PUT /v2/projects/{project_id}/functions/{function_id}/file, or with fun functions upload <name> <file.wasm>. has_file_set tells you whether a binary was uploaded.

Limits

Limit Value
Default execution timeout 5 seconds
Maximum execution timeout 60 seconds
Execution history retention 7 days

The first execution after an upload, or after the keep-alive timeout expires, includes compiling the module, which takes noticeably longer than later executions. Set keep_alive_timeout to keep a frequently used function loaded.

SDK

These host functions let your module interact with Fundamentum. They are imported from the fundamentum namespace:

Host function Purpose
ProduceMessage(topic, message) Publish a message on a topic of your project. topic is the topic's ID as a string (for example "42"), as returned by fun api v1 pub-sub list-pub-sub-topics. Asynchronous: no result is returned to your function
ProduceMessageWithHeaders(topic, message, headers) Same as ProduceMessage, with headers as a JSON object of header names and values
PublicAPIGet(route, token) Send a GET request to the Public API on route, with token as the bearer token, and return the response

Each argument is passed as a 64-bit integer: the upper 32 bits are a pointer into the module's memory and the lower 32 bits a length in bytes.

Go SDK

The Go SDK wraps the input and the host functions:

package main

import (
	"fmt"
	"os"

	sdk "<go-sdk-module-path>"
)

// ID of the project topic that receives the result.
const outputTopicID = "42"

func main() {
	input, err := sdk.ReadInput(os.Stdin)
	if err != nil {
		fmt.Fprintln(os.Stderr, "failed reading input:", err)
		os.Exit(1)
	}

	fmt.Fprintln(os.Stderr, "project", input.Context.ProjectID)

	sdk.ProduceMessage(outputTopicID, string(input.Input))
	fmt.Print(`{"ok":true}`)
}
Function Description
sdk.ReadInput(r io.Reader) (FunctionInput, error) Parse the input document. Input and Metadata values are decoded to bytes
sdk.ProduceMessage(topic, msg string) Call ProduceMessage
sdk.ProduceMessageWithHeaders(topic, msg string, headers map[string]string) Call ProduceMessageWithHeaders
sdk.Get(token string) func(route string) (map[string]any, error) Call PublicAPIGet with a token and return the decoded JSON

In other languages, read stdin and parse the JSON yourself. The host functions are available as WASI imports from the fundamentum namespace.

Execution history

Each execution is recorded with:

Field Description
source What triggered it: http or pubsub
started_at Start time
execution_time Duration in seconds
log What the function wrote to stderr
error The error message, empty on success

List executions with fun functions executions list --name <name> or GET /v2/projects/{project_id}/functions/{function_id}/executions. Executions are kept for 7 days.

What's next