A function is the smallest unit on the platform: a handler that receives an event, does its work and returns a result, with the platform taking care of containers, scaling, logs and traces. This tutorial writes one, runs it, deploys it and puts it behind a URL. There are two ways in, and both end at the same place: the browser editor when you want to see everything happen, and the CLI when the function lives in a repository.
- Write
Choose a runtime and save the handler
- Test
Run with test input and inspect the result
- Deploy
Publish the function version
- Call
Configure an API route and send a request
Deploying a function and exposing an HTTP route are separate actions. Verify the route, authentication and response.
Path A: in the browser#
1. Create the function#
Open Functions and press New Function. The dialog asks for a Name (hello is fine), a Runtime, the Handler in the form file.export (leave index.handler), a Timeout in milliseconds and Memory in megabytes. Keep the defaults for now; they are easy to change in Config later.
Two switches deserve a look. Allow Network Access is off by default: a function that only computes stays sealed, and one that calls external APIs opens the door explicitly. And if you already have code, Code ZIP uploads it in one go instead of typing it into the editor.
2. Write the handler#
The editor opens with a stub. Replace it with the handler below. A handler is an exported async function that receives the event and a context and returns whatever should be sent back:
exports.handler = async (event, context) => { // "Run" in the editor passes your JSON as `event`. A gateway route passes an // API Gateway-style event whose body is a string. Accept both. const input = typeof event.body === 'string' ? JSON.parse(event.body || '{}') : (event.body ?? event); const name = input.name || 'world'; console.log(`greeting ${name}`); // ends up in the run's logs and trace return { statusCode: 200, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message: `Hello, ${name}!`, at: new Date().toISOString() }), }; };
The small dance at the top is worth understanding. When you press Run in the editor, the JSON you type arrives as the event itself. When the same function is called through a gateway route, the event has the shape of an HTTP request with the body as a string. Reading both means the function behaves identically in the test panel and in production, and returning a statusCode plus body lets the gateway turn the result into a proper HTTP response.
3. Run it#
Press Run, enter {"name": "Ada"} as the JSON event and inspect the result and logs. A cold start or environment preparation can take additional time. Check that your code changes have been saved before running.
A run from the editor executes the current code in a real container of the chosen runtime. Errors show up as a stack trace pointing at the line, with the same logs you would see in production.
4. Deploy#
Press Deploy and follow the build and deployment status. The platform prepares the release and checks readiness before switching the active version. A failed build or readiness check must be resolved before the new version can serve requests. First-call latency depends on the runtime, dependencies and whether a serving replica is already running.
5. Give it a URL#
Open HTTP APIs, select an existing API or create one, and add a route: method POST, path /hello, target the hello function. An empty workspace API is not shown in the list. Choose Public only if this endpoint should accept unauthenticated requests; otherwise configure API Key or Bearer Token. Use the URL shown for that API.
The route is live as soon as it is saved. Call it from any terminal:
# The full URL of every route is shown on the Gateway page. The default # workspace API lives under /gw/<workspace-slug>/… curl -X POST "https://api.inquir.org/gw/<workspace-slug>/hello" \ -H "Content-Type: application/json" \ -d '{"name":"Ada"}' # {"message":"Hello, Ada!","at":"2026-09-05T12:00:00.000Z"} # The same route with API-key auth curl -X POST "https://api.inquir.org/gw/<workspace-slug>/hello" \ -H "X-Api-Key: $INQUIR_GATEWAY_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"Ada"}'
6. Watch it run#
The Traces tab of the function shows every invocation: when it ran, how long it took, what it returned, and the logs. Failed runs are marked and keep their stack traces. Runs in the sidebar shows the same for all functions of the workspace, with filters by status and time, which is where you usually start when something is wrong.
Path B: from the terminal#
When functions live in a repository, the CLI scaffolds a project, runs handlers locally and deploys them from the same folder, so the code reviews and CI you already have apply to functions as well:
npm install -g @inquir/compute-cli@latest inquir init # inquir.config.json, folders, a sample `hello` function inquir run hello --payload '{"name":"World"}' # runs locally — no account needed yet inquir login # browser pairing → a personal access token inquir use <workspace-slug> # the workspace to deploy into inquir deploy hello # package, upload, deploy — streams the build log inquir invoke hello --payload '{"name":"World"}' inquir logs hello # recent remote invocations inquir sync status # local vs deployed: in-sync / drift / missing
inquir init creates inquir.config.json, the folder layout and a sample hello function written with defineFunction from the SDK: the input schema is declared with zod, so invalid payloads are rejected before the handler runs, and the type of the input is inferred in the editor. inquir run executes it locally with the payload you pass, no account needed, which makes the loop of edit and run instant.
inquir deploy hello packages the function, uploads it and streams the build log until the version is live; inquir invoke calls the deployed version, and inquir logs shows its recent invocations. Run inquir sync status at any time to see which local functions are in sync with what is deployed, which have drifted, and which exist only on one side.
Where to go next#
The Functions reference describes the handler contract, environment variables and limits in full; the Gateway page covers auth modes, validation and webhook signatures; the SDK page shows defineFunction with typed inputs. When a function grows into a service that needs to stay up, the previous tutorial deploys it as an application.