Skip to content
This page View Markdown Open in ChatGPT Open in Claude

Custom API settings

The Basic Info tab of a custom API is a TypeScript object. It says where the API answers, who may call it, and how it behaves. It is always TypeScript, whatever language the code is written in : API Maker runs it itself when you save. So the tab shows TypeScript with a lock.

In short

  • path and requestMethod say where the API answers. Together they are unique in the account.
  • apiAccessType and authProviders say who may call it.
  • The other keys are optional : cache, request schemas, timeout, files, a sandbox of its own.
Page APIs & Logic → Custom API → the API → Basic Info.
Type T.ICustomApiSettingsTypes
URL /api/custom-api/<user path><path> with requestMethod. Path and method together are unique.
Basic Info
import * as T from 'types';
import { EType } from 'types';

let customApi: T.ICustomApiSettingsTypes = {
    name: 'Create Customer',                 // unique ; the folder in Git
    requestMethod: T.ERequestMethod.POST,
    path: '/customers',
    enableCaching: false,
    resetCacheOnModificationOf: [
        // 'DB:mongodb:shop:customers',        // a write to this table resets the cache of this API
        // 'CA:other_custom_api',              // a call of that custom API resets it
    ],
    acceptOnlyEncryptedData: false,
    // customApiTimeoutInSeconds: 10,
    errorList: [ 'Unable to process this request' ],   // translatable in i18n
    apiAccessType: T.EAPIAccessType.TOKEN_ACCESS,
    // authProviders: ['users_tg'],
    reqBodySchema: {
        first_name: { __type: EType.string, validations: { required: true } },
        phone: { __type: EType.number, validations: { min: 5 } },
    },
    fileUpload: { enable: false, allowFileUploadFields: [ T.EFilesVariables.files ], validations: {} },
};
module.exports = customApi;

The keys

Key Meaning
name Unique name, also the folder of the API in Git.
path, requestMethod Where it answers : GET, POST, PUT or DELETE. The path must match exactly : it holds no variables. Send values in the query or the body.
apiAccessType TOKEN_ACCESS (default), IS_PUBLIC, or NO_ACCESS for an API only your code calls.
authProviders The person tokens the call must carry. Absent : common.authProviders of the secret ; [] : the API user token alone.
enableCaching Cache the answer in Redis per body, query and person.
resetCacheOnModificationOf DB:instance:database:table, CA:custom API name : what drops the cached answers. Otherwise reset custom API cache.
acceptOnlyEncryptedData Refuse plain payloads : encrypted payloads.
reqBodySchema, reqQueryParametersSchema A schema for the body and the query : validated and converted before the code runs, checkable with is valid data for custom API.
customApiTimeoutInSeconds How long the code of the API and the hooks of its versions may run, in seconds, in the sandbox and with runOnNativeProcess alike. Empty : sandboxReqTimeout (13 seconds). A request which sends x-am-sandbox-timeout is given that time instead : time of a run.
runOnNativeProcess Run on the machine of the server instead of the sandbox : faster, less isolated ; console.log is not captured, use g.logger. The code finds the packages of the Sandbox Settings of its language (of its group, when it names one) : they are installed on the machine the first time it runs.
errorList The messages this API throws, listed for internationalization.
fileUpload enable, allowFileUploadFields (files…), and per field validations : minFileSizeBytes, maxFileSizeBytes, allowedExtensionsArr. See files.
swaggerDocs tag and parameters for the Swagger docs of the API users. parameters are written as in OpenAPI 3, or the way of Swagger 2 : { in: 'formData', name: 'files', type: 'file' } becomes a field of a form.
separateSandboxSettings Sandboxes of their own for this API : see below.

The language of the code of the API is chosen in the title bar of its editor, not here : see languages.

Separate sandbox

By default the code of a custom API runs in the sandboxes of its language, with the packages of the Sandbox Settings. An API which needs other packages, another runtime or version, or which must not share its sandboxes with the rest, names a group : every API of the account which names the same group shares its sandboxes, and no other code runs there.

Separate Sandboxes for Heavy APIs: Bun, Sandbox Count and Restarts10 chapters and the transcript
Reports in a sandbox of their own, on Bun
let customApi: T.ICustomApiSettingsTypes = {
    name: 'Monthly report',
    requestMethod: T.ERequestMethod.GET,
    path: '/reports/monthly',
    apiAccessType: T.EAPIAccessType.TOKEN_ACCESS,
    separateSandboxSettings: {
        enableSeparateSandboxForThis: 'reports',     // the group
        runtime: 'bun',                              // another runtime of the language of the code
        version: '1.4',
        sandboxCount: 1,
        autoRestart: { afterTheseMuchSeconds: 3600 }, // a new sandbox every hour, no request dropped
        packages: {
            allowAllPackagesOfAdmin: true,           // the packages of the Sandbox Settings, and :
            sandboxPackages: [{ name: 'pdfkit', version: '0.15.0' }],
        },
        // dockerFileOfSandbox: 'FROM {{AM_BASE_IMAGE}}\nRUN apt-get … \n{{AM_PACKAGES}}\n{{AM_RUNNER}}',
    },
};
Key Meaning
enableSeparateSandboxForThis The name of the group. Empty : the sandboxes of the language, and the keys below say nothing.
runtime, version A runtime of the language of the code (node or bun for TypeScript) and a tag of its image. The runtime wins over the one the code names. Absent : the ones of the Sandbox Settings, with the version and Dockerfile they keep for that very runtime (a group on Bun never takes the version of Node.js).
sandboxCount The most sandboxes of the group at a time, on each server : 1 to 50.
packages.sandboxPackages The packages of the group, from the registry of its language.
packages.allowAllPackagesOfAdmin true : the packages of the Sandbox Settings too. A package named in both is installed once, in the version of the group.
dockerFileOfSandbox A Dockerfile of the group, with the same markers.
autoRestart.afterTheseMuchSeconds A sandbox of the group gives its place to a new one after this many seconds (60 at least) : the new one starts while the old one still takes the requests, then the old one finishes what it runs. No request fails for it. Empty or 0 : never. The restart of the Sandbox Settings is not the group's.
  • The custom APIs of a group share it. Every API of the account which names the same group runs in the same sandboxes : all their packages are there, and what one leaves in g.shared the others find. So the group is what they say together : its runtime, version, Dockerfile, sandbox count and restart are said once, in any of them, and an API which names another value than another API of the group is refused when it is saved : The custom API 'monthly' of the group 'reports' names the version '1.3' : …. Name it in one of them only, or the same in each.
  • The hooks of the versions of the API run in the sandboxes of its group too, in the same request.
  • The group gets an image of its own (shared with any account which has the same settings), built when the API is saved.
  • Changing the settings of a group starts its sandboxes anew on every server.
  • Settings which can not be made are refused when the API is saved, in words : a runtime of another language, a version too old for its runtime, a package its registry does not take, a Dockerfile with CMD, a sandbox count out of range. So is a runtime, version or sandboxCount without a group : it would change nothing.
  • With runOnNativeProcess the code runs on the machine of the server : on the runtime of its group, with the packages of its group. The version, Dockerfile, sandbox count and restart are the ones of sandboxes : it has none.
  • API Testing of the admin panel, sending x-am-meta: true, is told the group in runBy (enableSeparateSandboxForThis, runtime, port) ; x-am-run-in-sandbox picks among the oldest sandboxes of the group.