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.
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"becomes12for anumberinput. 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). httpandhttpsonly.- Redirects are not followed — a
3xxresponse 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_LARGEin the Studio test,UPSTREAM_TOO_LARGEforekit.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.