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

How API Maker works

API Maker is a server you install, not a library you embed. Your apps call it over HTTP, it talks to your databases, and your own TypeScript runs inside it in a sandbox. This page shows the pieces once, so every other page makes sense.

The life of a request

The life of a request : app → Caddy → token and groups → pre hooks → the API → post hooks → reply Your app web · mobile · server or an AI agent Caddy HTTPS ends here :443 → :38246 API Maker one process, or a cluster behind Caddy Token & groups API gate · row gate 401 · 403 if not Pre hooks your code check · change · stop The API generated · custom system · third party Post hooks your code reshape · notify Reply JSON · XML YAML · text · file Redis cache answers again in µs Your databases MongoDB · SQL · Oracle The API asks the cache first when caching is on, then the database. Sandboxed : your code runs in Docker containers, apart from API Maker. x-am-authorization 200 · 201 with data, or 400 · 401 · 403 · 404 with every error at once
  1. Your app calls a URL such as GET /api/schema/admin/shop/main/customers?limit=10 with the token of its API user in x-am-authorization.
  2. Caddy (installed by the install script) ends HTTPS and forwards to API Maker on port 38246. WebSockets go to 38245.
  3. Token and groups : API Maker checks the token, finds the API user and its groups, and refuses the call with 401 (no valid token) or 403 (no group grants this API of this table). When the table asks for a person token too, that token is checked the same way.
  4. Pre hooks you wrote for the instance, the database, the table or this API run in order. They can change the request, add a filter such as "only the rows of this person", answer directly, or throw.
  5. The API runs : a generated or schema API talks to the database, a custom API runs your function in the sandbox, a system API does its job. With caching on, the answer comes from Redis when it is there.
  6. Post hooks run with the result and can reshape it, notify, or throw.
  7. The reply goes back in the envelope { success, statusCode, data | errors }, as JSON, XML, YAML or text, with the key case you asked for in the headers. WebSocket subscribers of that API or table get their notification.

Every step is logged when a log profile selects the API, and counted in the analytics dashboard.

One base URL, several families

The API families : one base URL, one token, five HTTP families and the code API Maker runs for you https://api.example.com/api/… one host, one token header, every family below Schema APIs /api/schema/… 17 per table · types, rules, encryption, ids from the schema Generated APIs /api/gen/… 17 per table · schemaless, data passes as it is Custom APIs /api/custom-api/… your TypeScript function, any path and method System APIs /api/system-api/… 24 ready APIs : tokens, encrypt, cache, events, indexes, checks Third party APIs /api/third-party/… bundles installed from the store deprecated, goes in v4 Run by API Maker, not called over HTTP Events after an API hit or from your code · Schedulers on intervals and cron · WebSocket events pushed to clients Process initializers when a sandbox starts · Migration scripts on deploy · Hooks around every API · Test cases
Family URL What it is Where it is described
Schema APIs /api/schema/<user-path>/<instance>/<database>/<table>/… 17 operations per table which apply the schema of the table All APIs
Generated APIs /api/gen/<user-path>/<instance>/<database>/<table>/… The same 17 operations, schemaless All APIs
Custom APIs /api/custom-api/<user-path>/<your path> Your TypeScript function behind the path and method you choose Custom APIs
System APIs /api/system-api/<user-path>/<name> Ready made APIs : tokens, encryption, hashing, secrets, Redis keys, cache resets, events, indexes, validations System APIs
Third party APIs /api/third-party/<user-path>/<bundle>/<version>/<path> Bundles installed from the API Maker store (deprecated, removed in v4) Third party APIs
Not over HTTP Events, schedulers, WebSocket events, process initializers, migration scripts, hooks and test cases : code API Maker runs for you

<user-path> is the API path of the admin or developer account which owns the item : admin for the first admin account. Each developer account has its own path, its own instances, secrets and code, on the same server.

The two tokens and the two gates

Two tokens, two gates : the API user (which application) and the person (which rows) 1 · get the tokens POST …/system-api/admin/token { "u": "shop_app", "p": "…" } an API user of API Maker → x-am-authorization POST …/system-api/admin/token { "name": "users_tg", "u": "alice", "p": "…" } a row of your users table → x-am-user-authorization Google, Azure AD, AWS Cognito and custom providers give the person token too : x-google-authorization… 2 · call an API with both GET /api/schema/admin/shop/main/orders x-am-authorization: eyJ… x-am-user-authorization: eyJ… Public APIs (IS_PUBLIC) need no token. Token access needs the API user, and the person only when the settings name an auth provider. 3 · two gates in API Maker API gate · the groups of the API user may this application call this API of this table ? which fields it may read and write · 403 when no group grants it Row gate · your pre hook of the rows this API reaches, which are this person's ? g.req.auth.authAMDB → find = { owner: person.id } only the rows of Alice, only the fields her app may see 401 : token missing or expired · 403 : no group grants the API
  • The API user is an application : your web app, your mobile app, a partner. It is created on the API user permissions page, gets a token from the token API with its username and password, and sends it in x-am-authorization. Its groups are the API gate : which APIs, tables and fields it may read and write.
  • The person is a row of your own users table, or a Google, Azure AD, AWS Cognito or custom identity. An auth provider turns it into a token sent in x-am-user-authorization (or the header of the provider). Your code reads it in g.req.auth, and a pre hook is the row gate : it narrows every request to the rows of that person.
  • A new account starts with an API user named default (password 12345, kept in the default secret under common.apiUserPasswords.default) and a group Default which allows everything. Replace both before you go live : one small group per screen is the pattern described in Handle role based permissions.
  • Public APIs (apiAccessType: IS_PUBLIC in the settings) skip both tokens.

Where your code runs

  • The sandbox. Custom APIs, hooks, events, schedulers, migrations, utility classes and test cases run in Docker containers apart from the API Maker process, with a time limit (13000 ms by default, the header x-am-sandbox-timeout changes it per call) and their own npm packages, installed from the sandbox settings. Every admin account gets its own sandbox containers.
  • The native process. A custom API with runOnNativeProcess: true runs inside API Maker itself, for the few cases that need it : native modules, a browser with Playwright, or the lowest possible latency. It is faster and less isolated.
  • The global object g. Your code gets one object with the request (g.req), the response (g.res), every API of API Maker (g.sys.db, g.sys.system, g.sys.cache), a logger and a shared space : Global object g.
  • TypeScript in the browser. You write the code in the admin panel, with the types of API Maker (import * as T from 'types') and the interfaces generated from your schemas (import * as db from 'db-interfaces'). Or in your own editor, with the local client syncing the files both ways.

The servers

One server after the install script : Caddy → PM2 (API Maker backend, WebSocket, admin panel) → Docker (MongoDB, Redis, sandboxes) → your databases Internet apps · users Your Ubuntu server 1 vCPU · 1 GB RAM is enough to start Caddy :80 · :443 (SSL) reverse proxy automatic HTTPS PM2 · Node.js 22 API Maker backend :38246 HTTP API :38245 WebSocket Admin panel static site · :4626 Docker MongoDB API Maker's own data · :38248 Redis cache · counters · :7479 Sandboxes your custom code runs here one container per admin Files /root/config/.env · /root/config/Caddyfile /root/projects/sava_api_maker · /root/logs · /root/docker-data Your databases MongoDB · MySQL · MariaDB PostgreSQL · SQL Server Oracle · TiDB · Percona on this server, or anywhere reached through the connection strings of your secret
  • API Maker is a Node.js 22 process run by PM2. cpuCount in its configuration starts one worker per CPU core. Several servers behind Caddy form a cluster : schedulers run once per cluster, WebSocket notifications reach every server through Redis.
  • MongoDB (a replica set) holds the data of API Maker itself : accounts, schemas, code, settings, logs. Your data stays in your databases.
  • Redis holds the cache, the auto increment counters and what the servers of a cluster share.
  • The admin panel is a static site served on port 4626 (or the domain you gave Caddy). It talks to the same API.
  • Sandboxes are Docker containers on the same server.
  • Your databases can be on the same server or anywhere the server can reach. The connection strings live in the default secret.

The install page shows what the install script sets up ; the deployment architectures on the website go from one server to a global fleet.

What happens on a save

The stages of a write through a schema API, in order, from the request to 201 or 400 POST body "price": "25" "name": " Mouse " Keys not in the schema : 400 Types "25" → 25 date, objectId Clean trim, case defaults conversionFun your function, its return is kept Secure encrypt · hash with your secret Ids ObjectID, UUID auto increment Rules required, min, length, email, enum validatorFun your rule, with the whole object 201 · saved, row returned ids and defaults filled in 400 · every error at once nothing is saved Generated APIs (/api/gen) skip all of this.

A write through a schema API is converted and checked before it reaches the database : keys not in the schema are refused, values get their types, strings are trimmed and cased, your conversionFun runs, fields are encrypted or hashed, ids and defaults are filled in, then the rules and your validatorFun decide. Everything wrong is answered at once, with 400 and one entry per problem, and nothing is saved. Table schema describes every option.

Everything is in Git

Schemas, settings, custom APIs, hooks, events, schedulers, utility classes, migrations, test cases and the security report are files in a Git repository. The admin panel commits and pushes them ; a Git pull on another server is the deployment. Secrets and notes never go to Git. See Git integration and Deploy API Maker for the upgrade of API Maker itself.