Platform CLI
Learn
Developer docs User guide Quickstart CLI and AI agents Blog
Company
Services About Contact Links Get started

Raytha Functions

Updated

A Raytha Function is a small JavaScript program stored in your Raytha database and run on the server by the V8 engine. You use one to answer a public URL, to compute something for a Liquid template, or to react when a content item is created, updated or deleted. This page covers what they are, how to create one, the limits, and what you must know before you expose one to the internet.

Your first function

Open the admin, go to Functions and create a function with trigger HTTP request, mark it active, and save this code. The developer name is hello.

function get(query) {
  return new JsonResult({ message: "Hello from Raytha", time: DateTime.UtcNow.ToString("o") });
}

Request it. No API key is needed, because HTTP functions are public:

curl -s "$RAYTHA_URL/raytha/functions/execute/hello"
{
  "message": "Hello from Raytha",
  "time": "2026-10-02T16:58:50.3942540Z"
}

The function returned a JsonResult. Raytha turned it into an application/json response. Every HTTP function must return one of the result helpers described in HTTP request trigger.

Triggers

The trigger type is chosen when you create the function. It decides how the function is called and which entry point Raytha looks for in your code.

TriggerDeveloper nameEntry pointCalled when
HTTP requesthttp_requestget(query), post(payload, query)A request reaches /raytha/functions/execute/{name} or the function's own route path. See HTTP request trigger.
Liquid templateliquid_templateAny function name you chooseA template calls raytha_function("name", "method", ...). See Liquid template trigger.
Content item createdcontent_item_createdrun(payload)After a content item is created, from the admin, the API or another function. See Content event triggers.
Content item updatedcontent_item_updatedrun(payload)After an item is edited or its settings change.
Content item deletedcontent_item_deletedrun(payload)Before an item is moved to the trash.

There is no timer or scheduled trigger. There is also no separate "webhook" trigger: inbound webhooks are HTTP functions and outbound ones are event functions that call HttpClient. See Webhook trigger.

What a function can use

Your code runs in a plain V8 engine with the ECMAScript standard library (JSON, Promise, Math, RegExp) and these extras that Raytha adds:

  • API_V1 calls the same service layer as the REST API, with no permission checks.
  • CurrentUser and CurrentOrganization describe the caller and the site.
  • Emailer and EmailMessage send mail through the SMTP settings.
  • HttpClient calls other servers.
  • Selected .NET types such as Guid, DateTime, Regex and StringBuilder.

There is no require, import, fetch or setTimeout. typeof returns "undefined" for each of them. The full list is in Built-in objects.

Creating and editing functions

Each function has a name, a developer name, a trigger type, an active switch and the code. HTTP functions also have an optional route path, which publishes the function at a URL of your choice. Raytha keeps a revision every time you save, and you can revert to one. You can also manage functions with the REST API under /raytha/api/v1/Functions or the raytha CLI. See REST API overview.

The developer name is lowercased, and every character other than a letter or digit becomes _. For HTTP functions, dots are kept, so feed.xml stays feed.xml. An inactive function answers 404.

Limits and configuration

Three settings control concurrency and time. Set them as environment variables or in appsettings.json.

SettingDefaultMeaning
RAYTHA_FUNCTIONS_MAX_ACTIVE5How many functions run at once. HTTP functions and content event functions share this pool.
RAYTHA_FUNCTIONS_TIMEOUT10000Milliseconds a function may run. After that the script is interrupted and the request gets 500.
RAYTHA_FUNCTIONS_QUEUE_TIMEOUT10000Milliseconds a call may wait for a free slot. After that an HTTP request gets 503.

Each call gets a fresh V8 engine. Nothing you store in a global variable survives to the next call, and two calls never share state. Keep state in content items.

Calls through HttpClient cannot reach localhost or private network addresses unless you set ALLOW_INTERNAL_URL_IMPORTS=true. Raytha checks the address it actually connects to, after DNS and redirects. See Configuration.

Security

Important An HTTP function is a public, anonymous endpoint that runs with full trust. Anyone on the internet can call it without signing in, and its API_V1 calls skip every permission check.

  • Only people with the Manage System Settings permission can create or edit functions. That permission is already full control of the site, because anyone holding it can also write code that runs as the server.
  • A function cannot create, edit or reset administrator accounts. The user functions in API_V1 refuse admin accounts.
  • Validate every input and keep the data you return to what a stranger may see. The function decides what to expose, not Raytha.
  • A JSON body is parsed into a value before post() runs. An empty body arrives as null, and any other text arrives as a string. The body is data: it is never placed into the script. Treat the endpoint as public input, and never put secrets in a function's response.
  • An unhandled script error returns the error text to the caller as the response body. Catch errors and return a short message instead.
  • HTTP functions do not see request headers or the raw body. Header-based signatures cannot be verified inside a function.

Gotchas

  • Return a result helper. Returning a bare object or string from an HTTP function gives a 500 "Invalid function result". Wrap it in JsonResult, TextResult or another helper.
  • MAX_ACTIVE=0 does not hide functions. It gives every HTTP call a 503 after the queue timeout and makes Liquid calls return nothing.
  • IDs are objects. A ShortGuid from API_V1 prints as [object Object] in a string concatenation. Call .ToString() on it.
  • Content event functions have no web request. Calls that look up an existing item by id may fail there. See Content event triggers.

Next steps