Skip to content

Methods

A Method is a server-side HTTP call defined in the Studio: it takes inputs, calls an external API (optionally with secrets) and returns the response.

INPUTS  →  HTTP REQUEST (server-side, secrets resolved)  →  RESPONSE

Typical uses: generate text with an AI provider, fetch prices or availability from a third-party API, look up weather, geocode an address…

A Method belongs to one site (template). Create and edit Methods in the site editor, from the Methods panel.


Anatomy of a Method

Setting Description
Name Human-readable name.
Slug Identifier used in templates: lowercase letters, digits and dashes (open-ai-answer). Unique within the site.
Description Shown in the editor's suggestions and hover documentation.
Enabled A disabled Method is never executed.
Exposure server — executed by the rendering engine only (datasources). public — can also be called from the site's JavaScript with ekit.methods.call().
Request Verb (GET, POST, PUT, PATCH, DELETE), URL, query parameters, headers and JSON body.
Inputs Values the Method expects from the caller.

Inputs

Each input has a name (letters, digits, _), a type — string, number or boolean —, a required flag and an optional default value.

  • A required input without a default must always be provided.
  • Values are converted to the declared type: "12" becomes 12 for a number input. An invalid value makes the call fail.

Variables

Inside the URL, query parameters, headers and body, use:

Variable Value
{{input.name}} Value of the input name
{{secrets.NAME}} Decrypted value of the secret NAME (server-side only)
GET https://api.example.com/search?q={{input.query}}
Authorization: Bearer {{secrets.EXAMPLE_API_KEY}}

In the JSON body, a value that is exactly one variable keeps its type:

{
  "model": "gpt-4o-mini",
  "max_tokens": "{{input.maxTokens}}",
  "messages": [{ "role": "user", "content": "Answer briefly: {{input.prompt}}" }]
}

Here max_tokens is sent as the number 256, not the string "256", while content is a string built from the input.

The editor warns you about two risky patterns:

  • an input used in the domain of the URL (https://{{input.host}}/…): it would let callers target any server;
  • a secret in the URL: prefer a header.

Testing a Method

The Test panel of the Method editor runs the Method with the values you enter and shows the status, duration, content type and response.

Save before testing

The test always runs the saved version of the Method. The Test button is disabled — with an explanation — while the Method is new or has unsaved changes.


Using a Method in a page: type: method datasources

A datasource can take its data from a Method instead of a table:

---
datasources:
  answer:
    type: method
    method: open-ai-answer
    inputs:
      prompt: '{{query.q}}'
      maxTokens: 256
---
<p>{{ekdata.answer.choices.0.message.content}}</p>
  • method — slug of an enabled Method of the site.
  • inputs — input values. They support the usual datasource variables: {{query.…}}, {{params.slug}}, {{params.lang}}, {{i18n.…}}.
  • when — optional condition, as for any datasource.

ekdata.<alias> contains the response body: parsed JSON when the API returns JSON, text otherwise.

If the Method is unknown or disabled, if an input is invalid, or if the API answers with an error status, ekdata.<alias> is null and the error is reported in the Studio preview. The body of an error response is never passed to the template.

{{#if ekdata.answer}}
  <p>{{ekdata.answer.choices.0.message.content}}</p>
{{else}}
  <p>{{ektrans 'ANSWER_UNAVAILABLE'}}</p>
{{/if}}

How often the Method runs

Pages are cached: the Method runs when the page is rendered, then its result is reused for the page's lifetime (cache.ttlSeconds, 300 seconds by default) — this lifetime is the freshness of the external data. Each distinct URL (for example each ?q=…) is rendered, and runs the Method, separately; a failed call is not cached. With ttlSeconds: 0, every page view runs the Method again. With paid APIs (AI providers…), use when to run it only when needed (for example when: '{{query.q}}') and keep inputs under control.


Calling a Method from JavaScript: ekit.methods.call

A Method with exposure public can be called from the site's JavaScript, for example when a visitor submits a form:

const result = await ekit.methods.call('open-ai-answer', { prompt: 'Hello' });

if (result.ok) {
  console.log(result.data);            // response body of the API
} else if (result.status === 429) {
  // the API (or Ekit) asks to slow down
} else {
  console.warn(result.error.code, result.error.message);
}

ekit.methods.call(slug, inputs) always resolves — it never throws — with:

Property Description
ok true when the API answered successfully
status HTTP status of the called API (also for UPSTREAM_ERROR), otherwise the status of the Ekit response
data response body on success, null otherwise
error { code, message } when ok is false
error.code When
INVALID_INPUT undeclared input, wrong type (types are strict: "3" is not a number), missing required input, text longer than 4,096 characters, invalid JSON
METHOD_NOT_FOUND unknown slug, Method disabled or with exposure server
ORIGIN_NOT_ALLOWED call from another website
PAYLOAD_TOO_LARGE request body over 16 KB
RATE_LIMITED too many calls — see below
UPSTREAM_ERROR the API answered with an error status (its body is never forwarded; status holds its HTTP status)
UPSTREAM_TIMEOUT the API did not answer within 15 seconds
UPSTREAM_TOO_LARGE the API response is larger than 2 MB
EXECUTION_FAILED the Method could not run (for example a blocked host) — details are in the server logs only
NETWORK_ERROR the browser could not reach the site (status is 0)

Limits

  • 30 calls per minute per visitor (IP address) and per Method.
  • 600 calls per minute per site, all visitors and Methods together.

These limits smooth bursts; they are not a budget protection. Any visitor can call a public Method: for a paid API, set a quota or spending cap with the provider.

Calls from other websites

The call is sent to the site's own address (/_ekit/methods/<slug>), so no CORS setup is needed. When the browser sends an Origin header, it must match the site's domain; otherwise the call is refused. Requests without an Origin header (servers, command-line tools) are accepted — this check is a safeguard, not an authentication.

In the editor

ekit.methods.call(' suggests the site's public and enabled Methods, then their inputs with type, required flag and description. See Editor IntelliSense.


Security and limits

  • Server-side only — the request, its URL, headers and secrets never reach the browser.
  • Public hosts only — Methods cannot call localhost, private networks (10.x, 192.168.x, 172.16–31.x…), link-local or cloud metadata addresses (169.254.169.254), whatever the form of the address (IP, decimal, hexadecimal, IPv6 or a domain name pointing to such an address).
  • http and https only.
  • Redirects are not followed — a 3xx response is returned as is.
  • Timeout — 15 seconds.
  • Response size — 2 MB at most, whatever the API announces: a larger response is cut off and the call fails (RESPONSE_TOO_LARGE in the Studio test, UPSTREAM_TOO_LARGE for ekit.methods.call, datasource error in a page).
  • Tests in the Studio — 30 per minute per user.
  • A Method can only use the secrets of its own site.