Server Functions

A server function is your code, deployed to Poly’s Knative FaaS and invoked over HTTP. Use this page when you need hosted integration logic, a webhook or job target, or a callable that any SDK language can execute.

When to use a server function

Prefer a server function when you need at least one of:

  • Hosted business logic that must run even when no client is connected

  • A target for API Endpoints (Webhooks), Jobs, or GraphQL Subscriptions

  • Vari secret injection inside the function body (client functions cannot resolve .inject())

  • A callable from another language’s SDK

  • Execution logs

Prefer an API Function Training when you are wrapping an existing HTTP API. Prefer a Client Functions for small same-language helpers.

Deploy

Write an exported function, then deploy it with your language CLI.

TypeScript:

async function helloWorld(): Promise<string> {
    return 'Hello Poly World!';
}
$ npx poly function add helloWorld ./hello-world.ts --context "myContext" --server

Python:

def hello():
    return "Hello Poly World!"
$ python -m polyapi function add hello hello.py --context mycontext --server

Full install, generate, and Glide workflows: TypeScript (Node), Python, Java, .NET (Beta), and Project Glide.

Optional deploy flags documented on the TypeScript page include --execution-api-key (runtime key used when the function executes) and --cache-poly-library=true.

You can also create or update via POST /functions/server. Async deploy (?deployAsync=true) returns HTTP 202 with an executionId; poll GET /functions/server/deploy-status/:id. Redeploy with POST /functions/server/:id/redeploy.

Execute

After npx poly generate or python -m polyapi generate:

import poly from 'polyapi';

(async () => {
    console.log(await poly.myContext.helloWorld());
})();
from polyapi import poly
print(poly.mycontext.hello())

REST: POST /functions/server/:id/execute. Client function IDs are rejected on this route.

Fire-and-forget

Set serverSideAsync on the server function when the caller should not wait for the result.

Execute then returns HTTP 202 with { executionId } instead of the function body. The function still runs on Poly.

Logs

Enable logs on the server function, invoke it, then read Logging (Canopy or Logs API). Retention and line-size limits are on that page.

Timeouts and alwaysOn: Limits and timeouts.

Client functions inside server functions

You can call a client function from a server function, and you can nest client functions (client-in-client).

Rules that bite:

  • Client functions are same-language only (TypeScript client in TypeScript server, Python client in Python server).

  • Vari .inject() does not resolve inside client code. Inject on the server function and pass the value in.

  • If a client function imports an npm/pip package, import that package in the server function too. Client code is not copied into the server image by itself.

See Client Functions.

Permissions

  • Create, update, delete, redeploy: CustomDev on the API key (v1).

  • Execute: Execute, plus access to the function in that environment.

A server function and a client function cannot share the same context + name in one environment.

Done

You have a server function when:

  1. function add --server (or Glide / POST /functions/server) returns a function id.

  2. Generate includes it in the SDK.

  3. poly.<context>.<name>(...) or POST /functions/server/:id/execute returns a result (or 202 if serverSideAsync is on).