# API Maker Documentation : Getting started > The pages of https://docs.apimaker.dev in the order of the navigation, each with its title, its description and its URL. The code is in TypeScript : the Markdown of a page (its URL with .md) has every language. --- # API Maker Documentation > Learn API Maker step by step - install it, connect a database, get REST APIs for every table, add your own logic in TypeScript, Python, Go, Rust and more, secure it with tokens and groups, and deploy with Git. Source: https://docs.apimaker.dev/index.html API Maker v4.0.0-beta.10 · The backend engine for the AI era **Connect a database. Get every API. Add your logic.** API Maker connects to your databases and gives every table secure REST APIs at once : 17 per MongoDB collection, 14 per SQL table. You add your own logic in custom APIs, hooks, schedulers and events, in TypeScript, Python, PHP, C#, Go, Rust, Java or Kotlin. Every API is locked by default, your code is checked for data leaks, and caching, logging, monitoring and Git deployment are built in. It all runs on your own servers, as one program written in Rust. - [Your first API in 10 minutes](https://docs.apimaker.dev/v4/docs/getting-started/first-api.html) - [Install on a server](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html) - [Run on your computer](https://docs.apimaker.dev/v4/docs/getting-started/local-run.html) - [How it works](https://docs.apimaker.dev/v4/docs/getting-started/how-it-works.html) ## Start here 1. **Install API Maker** On a blank Ubuntu server, one command installs everything : [Install on a server](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html). On your laptop, the [API Maker Launchpad](https://docs.apimaker.dev/v4/docs/getting-started/local-run.html) desktop app runs API Maker and its databases in Docker. ```bash curl -fsSL https://apimaker.dev/v4/install.sh > install.sh && bash install.sh --default --version=latest --license_key=YOUR_KEY ``` 2. **Connect a database** Put the connection string in the default [secret](https://docs.apimaker.dev/v4/docs/secrets/secrets.html) and add an [instance](https://docs.apimaker.dev/v4/docs/apis-all/overview.html#instances). Every table of it gets its [APIs](https://docs.apimaker.dev/v4/docs/apis-all/overview.html) right away. A new account even comes with a sample shop : instance, schemas, custom APIs and hooks to read. 3. **Call an API** Get a token of the [API user](https://docs.apimaker.dev/v4/docs/apis-security/api-user-permission.html) with the [token API](https://docs.apimaker.dev/v4/docs/apis-all/system-apis/system-generated-token-api.html), send it in `x-am-authorization`, and read your data : [Your first API](https://docs.apimaker.dev/v4/docs/getting-started/first-api.html) walks through it with curl. 4. **Add your logic** Write [custom APIs](https://docs.apimaker.dev/v4/docs/apis-all/custom-apis/user-created-custom-api.html), [hooks](https://docs.apimaker.dev/v4/docs/apis-all/hooks/preHook-api.html), [schedulers](https://docs.apimaker.dev/v4/docs/apis-all/schedulers/user-created-schedulers-api.html) and [events](https://docs.apimaker.dev/v4/docs/apis-all/events/user-created-events-api.html) in [TypeScript, Python, PHP, C#, Go, Rust, Java or Kotlin](https://docs.apimaker.dev/v4/docs/languages/index.html), with the [global object `g`](https://docs.apimaker.dev/v4/docs/pre-defined-terms/global-object-g.html) to reach every API of API Maker from your code. 5. **Secure and ship** [Groups](https://docs.apimaker.dev/v4/docs/apis-security/api-group-permission.html) decide which APIs, tables and fields each application may use, the [security report](https://docs.apimaker.dev/v4/docs/apis-security/api-security-report.html) finds the gaps, and a [Git pull](https://docs.apimaker.dev/v4/docs/Git/git.html) is the deployment. Go through [Before you go live](https://docs.apimaker.dev/v4/docs/security/go-live.html) first. ## Find your way - [How API Maker works](https://docs.apimaker.dev/v4/docs/getting-started/how-it-works.html) : The life of a request, the API families, the two tokens and where your code runs. - [All APIs at a glance](https://docs.apimaker.dev/v4/docs/apis-all/overview.html) : Every generated, schema, custom and system API with its method and URL, on one page. - [Table schema](https://docs.apimaker.dev/v4/docs/schema/schema.html) : Types, validations, conversions, defaults, ids, encryption, relations, concurrency control. - [The global object g](https://docs.apimaker.dev/v4/docs/pre-defined-terms/global-object-g.html) : Request, response, database, system and cache APIs, logger and shared space in your code. - [Code examples](https://docs.apimaker.dev/v4/examples/index.html) : A working snippet for every method of g.sys.db, g.sys.system and g.sys.cache. - [SSR websites](https://docs.apimaker.dev/v4/docs/ssr/index.html) : Websites in TSX rendered next to your data : routing, forms, sign-in, row rules, cache, UI libraries, templates. (new) - [Request headers](https://docs.apimaker.dev/v4/docs/apis-all/header/requestHeader.html) : Tokens, response case and format, encryption, caching, sandbox, tenant, language. - [Security](https://docs.apimaker.dev/v4/docs/apis-security/api-security-report.html) : Groups, API users, auth providers, single sign-on, encrypted payloads and the security report. - [Operations](https://docs.apimaker.dev/v4/docs/features/automatic-caching.html) : Caching, logs, dashboards, deployment of API Maker itself and its configuration. - [Cheat sheet](https://docs.apimaker.dev/v4/docs/cheat-sheet.html) : URLs, headers, query params and the g object on one page, to keep next to your editor. - [Docs for AI assistants](https://docs.apimaker.dev/v4/docs/ai/llms.html) : llms.txt, the Markdown twin of every page, and how to point an agent at this documentation. (new) - [Release notes](https://docs.apimaker.dev/v4/docs/blog/release-notes/release_notes_summary.html) : What changed in every version, from v1.0.0 to v4.0.0-beta.10. - [Benchmarks](https://docs.apimaker.dev/v4/docs/benchmarks/index.html) : Requests per second and memory on 7 Linode servers, 1 to 8 vCPUs, shared and dedicated CPU, on MongoDB, PostgreSQL and MySQL, with the full autocannon output. ## What you get with every table | | Schema APIs `/api/schema` | Generated APIs `/api/gen` | |---|---|---| | Read | get all, get all by stream, get by id, query, query by stream, count, distinct, distinct with query, aggregate (MongoDB) | the same | | Write | save single or multiple, master save, update by id, update many, replace by id (MongoDB), array operations (MongoDB), remove by id, remove by query | the same | | Applies the [schema](https://docs.apimaker.dev/v4/docs/schema/schema.html) | types, validations, conversions, defaults, ids, encryption, concurrency control | no : data passes as it is | | Filters | [find](https://docs.apimaker.dev/v4/docs/apis-all/query-params/find.html) with `$in`, `$gt`, `$like`, `$regex`, `$and`, `$or`… and [find and join](https://docs.apimaker.dev/v4/docs/apis-all/query-params/find.html#find-and-join-fields-of-related-tables) across tables | the same | | Related data | [deep populate](https://docs.apimaker.dev/v4/docs/apis-all/query-params/deep.html) across tables, databases and instances | the same | | Output | JSON, XML, YAML, text, any key case, flat objects, encrypted : [headers](https://docs.apimaker.dev/v4/docs/apis-all/header/requestHeader.html) | the same | Every one of them can run [pre and post hooks](https://docs.apimaker.dev/v4/docs/apis-all/hooks/preHook-api.html), be [cached](https://docs.apimaker.dev/v4/docs/features/automatic-caching.html), be [logged](https://docs.apimaker.dev/v4/docs/logs/logs-and-dashboards.html#log-profiles), send [WebSocket notifications](https://docs.apimaker.dev/v4/docs/pages/web-socket-event-page.html) and [emit events](https://docs.apimaker.dev/v4/docs/apis-all/events/user-created-events-api.html). ## Supported databases MongoDB · MySQL · MariaDB · PostgreSQL · Microsoft SQL Server · Oracle Database · TiDB · Percona XtraDB, in one account at the same time, with queries and [deep populate](https://docs.apimaker.dev/v4/docs/apis-all/query-params/deep.html) across them. The [connection string](https://docs.apimaker.dev/v4/docs/Database-connection-string/mongodb-connection-strings.html) pages show the format for each one. ## Watch [API Maker features quick walkthrough (version 3)](https://youtu.be/7CMinfkIDCE) More on the [Learn API Maker](https://www.youtube.com/playlist?list=PLfJ8NnUMaDUYNNZUX5M_KcIzn9qGCNj43) playlist. These videos were recorded on API Maker 3 : the screens of version 4 look different, and the API Maker store they show is gone. ## Stay in touch [Twitter](https://twitter.com/api_maker) · [LinkedIn](https://www.linkedin.com/company/api-maker) · [YouTube](https://www.youtube.com/@api_maker) · report a problem at [API Maker Planning](https://github.com/APIMaker-dev/API-Maker-Planning/issues) · write to [contact@apimaker.dev](mailto:contact@apimaker.dev). --- # How API Maker Works > The moving parts of API Maker in one page - the life of a request, the API families on one base URL, the two tokens and the two gates, where your code runs in any of its languages, and what the servers look like. Source: https://docs.apimaker.dev/v4/docs/getting-started/how-it-works.html 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 code, in TypeScript, Python, PHP, C#, Go, Rust, Java or Kotlin, runs beside it in sandboxes. This page shows the pieces once, so every other page makes sense. ## The life of a request > Diagram : The life of a request : app → Caddy → token and groups → pre hooks → the API → post hooks → reply > > The life of a request in API Maker : the app calls through Caddy, API Maker checks the token and the groups, runs the pre hooks, the API itself against the database or the cache, the post hooks, and replies in JSON, XML or YAML. 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` : the APIs and the WebSockets share that port. 3. **Token and groups** : API Maker checks the token, finds the API user and its [groups](https://docs.apimaker.dev/v4/docs/apis-security/api-group-permission.html), 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](https://docs.apimaker.dev/v4/docs/apis-all/response-format.html) `{ success, statusCode, data | errors }`, as JSON, XML, YAML or text, with the key case you asked for in the [headers](https://docs.apimaker.dev/v4/docs/apis-all/header/requestHeader.html). WebSocket subscribers of that API or table get their notification. Every step is logged when a [log profile](https://docs.apimaker.dev/v4/docs/logs/logs-and-dashboards.html#log-profiles) selects the API, and counted in the analytics dashboard. ## One base URL, several families > Diagram : The API families : one base URL, one token, four HTTP families, your code in any language and the code API Maker runs for you > > The API families of API Maker on one base URL : schema APIs under /api/schema, generated APIs under /api/gen, custom APIs under /api/custom-api, system APIs under /api/system-api, the code of yours in nine runtimes, and the code API Maker runs on its own : events, schedulers, WebSocket events, process initializers and migrations. | Family | URL | What it is | Where it is described | |---|---|---|---| | Schema APIs | `/api/schema/////…` | The operations of a table (17 on MongoDB, 14 on SQL tables), which apply the [schema](https://docs.apimaker.dev/v4/docs/schema/schema.html) of the table | [All APIs](https://docs.apimaker.dev/v4/docs/apis-all/overview.html) | | Generated APIs | `/api/gen////
/…` | The same operations, without a schema | [All APIs](https://docs.apimaker.dev/v4/docs/apis-all/overview.html) | | Custom APIs | `/api/custom-api//` | Your function, in any [language](https://docs.apimaker.dev/v4/docs/languages/index.html), behind the path and method you choose | [Custom APIs](https://docs.apimaker.dev/v4/docs/apis-all/custom-apis/user-created-custom-api.html) | | System APIs | `/api/system-api//` | Ready made APIs : tokens, encryption, hashing, secrets, Redis keys, cache resets, events, indexes, validations | [System APIs](https://docs.apimaker.dev/v4/docs/apis-all/system-apis/system-generated-token-api.html) | | Not over HTTP | | [Events](https://docs.apimaker.dev/v4/docs/apis-all/events/user-created-events-api.html), [schedulers](https://docs.apimaker.dev/v4/docs/apis-all/schedulers/user-created-schedulers-api.html), [WebSocket events](https://docs.apimaker.dev/v4/docs/pages/web-socket-event-page.html), [process initializers](https://docs.apimaker.dev/v4/docs/features/process-initializers.html), [migration scripts](https://docs.apimaker.dev/v4/docs/features/database-migration.html), [hooks](https://docs.apimaker.dev/v4/docs/apis-all/hooks/preHook-api.html) and [test cases](https://docs.apimaker.dev/v4/docs/test-cases/test-cases.html) : code API Maker runs for you | | `` is the API path of the admin or developer account which owns the item : `admin` for the first admin account. Each [developer account](https://docs.apimaker.dev/v4/docs/features/team-work.html#developer-accounts) has its own path, its own instances, secrets and code, on the same server. ## The two tokens and the two gates > Diagram : Two tokens, two gates : the API user (which application) and the person (which rows) > > Two identities on every request : the API user token from the token API in x-am-authorization tells which application calls, and the token of a person from a token generator in x-am-user-authorization tells who the person is. Groups of the API user decide which APIs, tables and fields may be called ; pre hooks decide which rows belong to the person. - The **API user** is an application : your web app, your mobile app, a partner. It is created on the [API user permissions](https://docs.apimaker.dev/v4/docs/apis-security/api-user-permission.html) page, gets a token from the [token API](https://docs.apimaker.dev/v4/docs/apis-all/system-apis/system-generated-token-api.html) with its username and password, and sends it in `x-am-authorization`. Its [groups](https://docs.apimaker.dev/v4/docs/apis-security/api-group-permission.html) 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](https://docs.apimaker.dev/v4/docs/authorization/AMDB.html) 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](https://docs.apimaker.dev/v4/docs/authorization/handle-role-based-permissions.html). - Public APIs (`apiAccessType: IS_PUBLIC` in the [settings](https://docs.apimaker.dev/v4/docs/settings/apiSettings.html)) skip both tokens. ## Where your code runs - **The sandbox.** Your code runs in Docker containers of its account, apart from the API Maker process. Each call gets a time to run : the one its item names (seconds for a custom API, minutes for a scheduler, an event listener, a migration script or a process initializer), else `13000` ms. The header `x-am-sandbox-timeout` changes it per call ([time of a run](https://docs.apimaker.dev/v4/docs/settings/sandboxSettings.html#time-of-a-run)). Custom APIs, hooks, event listeners, schedulers, migration scripts, process initializers, utility classes and test cases are written in any of the [languages](https://docs.apimaker.dev/v4/docs/languages/index.html) : TypeScript on Node.js or Bun, Python, PHP, C#, Go, Rust, Java or Kotlin. Each language has its own sandboxes, built from the runtime, version, packages and Dockerfile of the [sandbox settings](https://docs.apimaker.dev/v4/docs/settings/sandboxSettings.html) : nothing is installed that the account did not add. - **The native process.** A custom API with `runOnNativeProcess: true` runs on the machine of the server instead of in Docker, in one runner per runtime shared by every account (the runtime must be installed there : `node`, `python3`…), for the few cases that need it : a browser with [Playwright](https://docs.apimaker.dev/v4/docs/guides/browser-automation.html), or the lowest possible latency. It is faster and less isolated. Like a sandbox, that runner answers what the code asks of `g.sys` itself (the databases, Redis) and hands only the answer back to the server. - **Settings run in the server.** Code which only describes (the Basic Info of a custom API, the settings of APIs, schemas, the texts of internationalization, secrets) is TypeScript which API Maker runs itself, the moment you save it : what it exports is JSON for the database, so it needs no sandbox. It imports `types` and your utility classes written in TypeScript, no packages : [where settings run](https://docs.apimaker.dev/v4/docs/languages/index.html#settings-run). - **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, in every language : [Global object g](https://docs.apimaker.dev/v4/docs/pre-defined-terms/global-object-g.html). - **Code in the browser.** You write the code in the admin panel : TypeScript 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 another language picked above the editor. Saving builds the code of compiled languages at once, and what does not compile is told in the console of the account. Or in your own editor, with the [local client](https://docs.apimaker.dev/v4/docs/features/developer-tools.html#your-own-editor) syncing the files both ways. ## The servers > Diagram : One server after the install script : Caddy → systemd (API Maker : APIs, WebSockets, admin panel) → Docker (MongoDB, Redis, sandboxes) → your databases > > What the installer sets up on one Ubuntu server : Caddy on ports 80 and 443 in front, API Maker run by systemd as the service api_maker_be (one program : the APIs and the WebSockets on port 38246, the admin panel on port 4626), MongoDB and Redis in Docker for the internal data of API Maker, sandbox containers for your code, and your own databases anywhere. - **API Maker** is one process per server, run by systemd : systemd starts it when the server boots and again if it stops. Its threads use every core ([one process, every core](https://docs.apimaker.dev/v4/docs/am-resources/api-maker-configurations.html#one-process)). Several servers behind Caddy form a cluster : schedulers are spread over the servers and run once per tick, a saved change and 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 that API Maker serves itself on a port of its own (`4626`, the `adminPanel` [settings](https://docs.apimaker.dev/v4/docs/am-resources/api-maker-configurations.html#server)) : Caddy puts it on port `80` or on the domain you gave it. It talks to the same API, through an encrypted channel of its own. That channel keeps what the panel sends from whoever only listens on the way ; it does not prove to the browser that it is your server which answers. Only HTTPS does : give the install script a domain (Caddy then serves the panel and the API over HTTPS), or put a proxy with a certificate in front, before people rely on the installation. - **Sandboxes** : your code runs in Docker containers called sandboxes, one per language of an account. When one is busy, API Maker starts another, up to the [sandbox count](https://docs.apimaker.dev/v4/docs/settings/sandboxSettings.html#sandbox-count). - **Your databases** can be on the same server or anywhere the server can reach. The [connection strings](https://docs.apimaker.dev/v4/docs/Database-connection-string/mongodb-connection-strings.html) live in the default [secret](https://docs.apimaker.dev/v4/docs/secrets/secrets.html). The [install page](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html) shows what the install script sets up ; the [deployment architectures](https://apimaker.dev/architectures) on the website go from one server to a global fleet. ## What happens on a save > Diagram : The stages of a write through a schema API, in order, from the request to 201 or 400 > > What a schema API does to every write : refuses unknown keys, converts the types, trims and cases strings, runs your conversion function, encrypts or hashes, fills ids and defaults, runs the rules and your validator function, then saves and answers 201, or answers 400 with every error at once and saves nothing. 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](https://docs.apimaker.dev/v4/docs/schema/schema.html) 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 never go to Git. See [Git integration](https://docs.apimaker.dev/v4/docs/Git/git.html) and [Deploy API Maker](https://docs.apimaker.dev/v4/docs/features/deploy-api-maker.html) for the upgrade of API Maker itself. - [Next : your first API →](https://docs.apimaker.dev/v4/docs/getting-started/first-api.html) - [All APIs at a glance](https://docs.apimaker.dev/v4/docs/apis-all/overview.html) - [Install on a server](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html) --- # Install API Maker on a Server > Put API Maker v4 on your own Ubuntu server with one command - one program for the APIs, the WebSockets and the admin panel, MongoDB and Redis in Docker, Caddy with HTTPS. The flags, what it asks and does, upgrades and rollbacks, a second server, the files, and the manual setup. Source: https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html API Maker v4 is one program for Linux : one process serves your APIs, the WebSockets and the admin panel on every core of the server, and the code of your accounts runs in Docker sandboxes. Nothing of Node.js is installed on the server. One command sets up a fresh Ubuntu server with everything around it : MongoDB and Redis in Docker, systemd to keep API Maker running, and Caddy in front with HTTPS. - [The install script](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html#install-with-one-command) : (API Maker v4) · One command in the terminal of a fresh Ubuntu server installs everything on that server and prints the admin panel URL. Run it again to upgrade : a version which does not start is rolled back on its own. Run it on more servers to build a cluster. - [API Maker Launchpad](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html#deploy-with-api-maker-launchpad) : The desktop app for macOS, Windows and Linux : draw an architecture on a diagram, and it installs API Maker v4 on your servers over SSH. It also moves a server of API Maker v3 to v4. ## Install with one command On a fresh Ubuntu server, one command installs everything and starts API Maker. The installer prints what it does at every step, and ends with the URLs, the default users and the commands to start and stop. > Diagram : One server after the install script : Caddy → systemd (API Maker : APIs, WebSockets, admin panel) → Docker (MongoDB, Redis, sandboxes) → your databases > > What the installer sets up on one Ubuntu server : Caddy on ports 80 and 443 in front, API Maker run by systemd as the service api_maker_be (one program : the APIs and the WebSockets on port 38246, the admin panel on port 4626), MongoDB and Redis in Docker for the internal data of API Maker, sandbox containers for your code, and your own databases anywhere. | | | |---|---| | Server | Ubuntu 22.04, 24.04 or 26.04, x86-64 or ARM64, the root user, systemd. 20 GB of disk or more ; on x86-64 a CPU with AVX (MongoDB needs it). 1 CPU and 1 GB of RAM run it : the installer adds swap. | | Command | `curl -fsSL https://apimaker.dev/v4/install.sh > install.sh && bash install.sh --default --version=latest --license_key=YOUR_KEY` | | Installs | Docker, MongoDB and Redis as containers, the Oracle Instant Client, Caddy, and API Maker itself in `~/projects/api_maker`, run by systemd as the service `api_maker_be`. | | Writes | `~/config/.env` (the [configuration](https://docs.apimaker.dev/v4/docs/am-resources/api-maker-configurations.html)), `~/config/Caddyfile`, the license file. Each one is backed up first, and the answers of an earlier installation are its defaults. | | Prints | The state of the services, the admin panel URL, the API and WebSocket URLs, the default users, the commands to start, stop, watch and upgrade API Maker. | ### 1. Run the installer ```sh curl -fsSL https://apimaker.dev/v4/install.sh > install.sh && bash install.sh --default --version=latest --license_key=YOUR_KEY ``` Every question has a flag, so the installer also runs without a terminal (a cloud-init script, `curl … | bash`) : what no flag answers takes its default. | Flag | Meaning | |---|---| | `--license_key=YOUR_KEY` | The license key of your account (write to [contact@apimaker.dev](mailto:contact@apimaker.dev) for one). It is written to `license.txt` and bound to the server. | | `--version=latest` | The version of API Maker to install, or an exact one like `--version=4.0.0`. Run it again to upgrade or to reinstall. | | `--default` | Takes the default of every question which has one : the ports, the user names, new passwords, the swap. The domains of SSL have none and are still asked. | | `--primary`, `--secondary` | The first server of an installation, or one more server which uses its MongoDB and Redis. Asked when not given. | | `--ip=203.0.113.10` | The public IPv4 address of the server. Found on its own and asked to confirm : some providers answer with the address of a gateway. On an upgrade without SSL, the default is the address the earlier installation confirmed. | | `--caddy=yes` | Caddy in front of API Maker. `no` on a server whose ports 80 and 443 belong to another web server : API Maker then answers on its own ports. | | `--ssl=no` | `yes` : HTTPS with certificates of Let's Encrypt, renewed by Caddy, on `--api_domain=`, `--ws_domain=` (the domain of the APIs when not given) and `--panel_domain=`. Each domain has to point to the server first ; `--skip_dns_check` takes it anyway. | | `--qa_uat_prod=no` | `yes` for a QA, UAT or PROD environment of a project : `passDBEncryptDecrypt` is then asked, it is the one of the DEV server of the same git repository. | | `--mongoVersion=8.0.10` | The MongoDB image to run. | | `--package=` | A release archive to install instead of downloading one : for a server without access to npm, or a build of your own (`scripts/release/build.sh` of api_maker_be_rust). | ### 2. What it asks Without `--default`, and for what no flag answers : 1. **Primary** or **secondary** server, and the **public IP address** of the server. 2. **Do you want to install the Caddy server?** and **Do you want to install SSL?**, then the domains of the APIs, of the WebSockets and of the admin panel. 3. **Are you setting up a server of a QA | UAT | PROD environment?** 4. The size of the swap file, when the server has less swap than memory (2 to 8 GB). 5. On a primary server : the port, user name and password of MongoDB, the port and password of Redis. On a server installed before, **Do you want to re-install MongoDB?** and **Redis?** : no keeps them, with their data. 6. The port of API Maker (`38246` : its APIs and its WebSockets) and of its admin panel (`4626`), and the three secrets `passCommunication`, `passJWT` and `passDBEncryptDecrypt` : new random ones, or the ones of the earlier installation, taken as they are. 7. On a secondary server : its name, the three secrets and the MongoDB and Redis connection strings of the primary server. ### 3. What it does 1. Checks the server : Ubuntu, root, systemd, the processor, glibc 2.35 or newer, the disk, AVX. 2. Stops API Maker when it runs, and takes it out of PM2 when PM2 ran it (an installation of the Node.js edition) : whatever else PM2 runs stays. Until the new version is in place, a failure starts the old API Maker again. 3. Installs Docker if needed, gives the network of the server [room for many connections](https://docs.apimaker.dev/v4/docs/getting-started/install-by-hand.html#network) (`/etc/sysctl.d/90-api-maker.conf`), then starts **MongoDB** (container `mongodb_api_maker`, a replica set of one member with a key of its own, data in `~/docker-data`) and **Redis** (container `redis_api_maker`). 4. Installs the Oracle Instant Client in `/opt/oracle/instantclient` : instances of Oracle need it, a failure here is only a warning. 5. Downloads API Maker for the processor of the server (the npm package `@sava-info-systems/api-maker-engine-linux-x64` or `-arm64`, read with `curl` : npm itself is not needed), checks it against the hash npm publishes, and runs it once (`api_maker_be --version`) before anything else changes. Every version has its own folder, `~/projects/api_maker/releases/`, and `~/projects/api_maker/current` points to the one that runs. 6. Writes `~/config/.env` : the connection strings, the secrets, the ports, the folder of the admin panel and where the panel reaches API Maker (`BE_HOST_PORT`). The lines of the earlier `.env` it does not write itself are kept. 7. Sets API Maker up as the **systemd** service `api_maker_be`, starts it and waits until it answers. A version which does not start is rolled back to the one which ran before. systemd starts API Maker again a second after it stops, and at every boot. Its log is `~/logs/api_maker_be.txt`, rotated past 50 MB. 8. Installs **Caddy** (the release of Caddy, checked against its SHA-512), writes `~/config/Caddyfile` and runs it as the systemd service `caddy`, so it comes back after a reboot : the admin panel on port 80, the APIs on port 8080 and the WebSockets on port 8081, or each on its own domain over HTTPS. 9. Registers the MAC address of the server for the license, keeps the last three versions, and prints the summary. **The end of the output** ```text ———— API Maker, run by systemd ———— api_maker_be.service active (running), enabled at boot, PID 4224, 0 restarts caddy.service active (running) ———— Important URLs ———— Admin panel http:// APIs http://:8080 Web sockets ws://:8081 ———— Default users (change their passwords after the first sign in) ———— root@root.com R00t_123456789 admin@admin.com Admin_123456789 Before you go live https://docs.apimaker.dev/v4/docs/security/go-live.html ———— Commands ———— [START] systemctl start api_maker_be [STOP] systemctl stop api_maker_be [RESTART] systemctl restart api_maker_be [STATUS] systemctl status api_maker_be [LOGS] tail -f /root/logs/api_maker_be.txt [UPGRADE] bash install.sh --version=latest ``` `systemctl stop api_maker_be` stops API Maker until the next boot ; `systemctl disable --now api_maker_be` keeps it stopped after a reboot too. The installer writes its own log to `~/logs/install/`. ### 4. First sign in - Open the admin panel URL, sign in as `admin@admin.com` and change both passwords : the root user in **Root Settings**, the admin user in its profile. - The admin account comes with a [sample shop](https://docs.apimaker.dev/v4/docs/getting-started/first-api.html) : try its APIs, then add your own [instance](https://docs.apimaker.dev/v4/docs/apis-all/overview.html#instances). ### Upgrade and roll back - **Upgrade** : run the same command again, with `--version=latest` or a version. The answers of the installation are the defaults, MongoDB and Redis stay, and the new version takes the place of the old one only once it has started. - **Roll back** by hand : point `current` at a version kept in `releases`, then restart. ```bash ls ~/projects/api_maker/releases ln -sfn ~/projects/api_maker/releases/4.0.0 ~/projects/api_maker/current systemctl restart api_maker_be ``` - **From the Node.js edition (v1 to v3)** : run the installer on that server and answer no to re-installing MongoDB and Redis. API Maker v4 takes the place of the service `api_maker_be` with the same MongoDB, Redis and secrets ; the uploaded files and the license file are copied, and the folder `~/projects/sava_api_maker` is left as it was. The service `api_maker_fe` goes : API Maker serves the admin panel itself. The WebSockets move to the port of the APIs : a client which reached `:38245` directly connects to `:38246` (behind Caddy, `:8081` stays what it was). ### A second server - Run the same command on the next server and answer **secondary** : it installs API Maker only, with the MongoDB and Redis of the primary server (their connection strings and the three secrets are in `~/config/.env` there). - The installer then prints the line to change in the Caddyfile of the primary server, so one address spreads the requests over every server : `reverse_proxy 127.0.0.1:38246 :38246`, then `systemctl restart caddy` there. Only the primary server needs to reach port `38246` of the others. Every server shows on the [Server Node Configurations](https://docs.apimaker.dev/v4/docs/logs/logs-and-dashboards.html#servers) dashboard, and the [schedulers](https://docs.apimaker.dev/v4/docs/apis-all/schedulers/user-created-schedulers-api.html) are spread over them. ### The files on the server | Path | What it is | |---|---| | `~/projects/api_maker/current` | The version that runs : `api_maker_be` (the server), `am_tools` (the compilers and libraries the server starts when code is saved), `am_agent` (the program inside every sandbox), `admin-panel/`. | | `~/projects/api_maker/releases/` | The versions installed, the last three. | | `~/projects/api_maker/uploads`, `license.txt` | Files uploaded through the APIs, the license. They stay from one version to the next. | | `~/config/.env` | The settings of API Maker ([configuration](https://docs.apimaker.dev/v4/docs/am-resources/api-maker-configurations.html)). Backups in `~/config/bkp_env`. | | `~/config/Caddyfile` | The sites of Caddy. Backups in `~/config/bkp_caddyfile`. | | `~/config/api_maker/` | The environment of the service and the rotation of its log. | | `~/config/mongodb_api_maker.yml`, `redis_api_maker.yml`, `keyfile` | MongoDB and Redis, with Docker Compose. | | `~/docker-data` | The data of MongoDB and Redis. | | `~/logs/api_maker_be.txt`, `~/logs/install/` | The log of API Maker, the logs of the installer. | | `/etc/systemd/system/api_maker_be.service` | The service. Caddy : `caddy.service`, with `/etc/systemd/system/caddy.service.d/api-maker.conf`. | | `/etc/sysctl.d/90-api-maker.conf`, `/etc/modules-load.d/api-maker.conf`, `/etc/modprobe.d/api-maker.conf` | The limits of the network and of the open files : [room for many connections](https://docs.apimaker.dev/v4/docs/getting-started/install-by-hand.html#network). | ## Choose an architecture Start on one server and grow without changing your APIs : API Maker keeps its state in MongoDB and Redis, so adding servers is a matter of configuration, not code. The website describes [13 reference architectures](https://apimaker.dev/architectures), each with a live diagram, the size of every server and the configuration to copy. API Maker Launchpad deploys the everyday ones straight from its diagram : | Architecture | What it is | In API Maker Launchpad | |---|---|---| | [All-in-one server](https://apimaker.dev/architectures/single-server) | API Maker, its MongoDB, Redis and your database on a single VPS. | The **All in one** layout. | | [Separate database server](https://apimaker.dev/architectures/separate-database) | API Maker on one VPS, your databases on servers of their own. | The **App + data** layout. | | [Dedicated data tier](https://apimaker.dev/architectures/dedicated-data-tier) | A stateless API server, with the MongoDB and Redis of API Maker on servers of their own. | The **Dedicated databases** layout. | | [Environments with Git](https://apimaker.dev/architectures/environments) | DEV, QA, UAT and PROD, each with its own servers and data. | One environment per stage, in one project. | | [Load-balanced API servers](https://apimaker.dev/architectures/load-balanced) | Several API Maker servers behind a load balancer, sharing one data tier. | The **Load balanced** layout ; add API Maker servers at any time. | | [Real-time events across servers](https://apimaker.dev/architectures/realtime-websockets) | WebSocket clients on any server, changes made on any server. | Any layout with several API Maker servers : they share Redis. | | [Clustered Redis and databases](https://apimaker.dev/architectures/clustered-data) | No single data node to lose. | API Maker's MongoDB as a replica set, its Redis as a cluster, your databases replicated. | | [High availability](https://apimaker.dev/architectures/high-availability) | A spare for every tier. | Several gateways, API Maker servers and database replicas ; the floating IP is set at your provider. | [Many projects on one platform](https://apimaker.dev/architectures/multi-project) and [a database per customer](https://apimaker.dev/architectures/multi-tenant) are features of API Maker itself and work on any of these layouts. [Multi-cloud](https://apimaker.dev/architectures/multi-cloud), [geo-routing](https://apimaker.dev/architectures/geo-routing) and the [global enterprise platform](https://apimaker.dev/architectures/global-enterprise) combine the same pieces across providers and regions : their pages show how. ## Deploy with API Maker Launchpad The **Cloud** mode of [API Maker Launchpad](https://docs.apimaker.dev/v4/docs/getting-started/local-run.html), the desktop app, installs API Maker on servers you rent anywhere, over SSH from your computer : add the servers, pick a layout on the diagram, press **Deploy**. It also sets up your databases with their replication, a reverse proxy with HTTPS and the firewall, and deploys new versions with rolling updates. See [Cloud mode](https://docs.apimaker.dev/v4/docs/getting-started/local-run.html#cloud-mode). ## By hand The pieces are ordinary : one program kept running by systemd, MongoDB as a replica set, Redis, and any reverse proxy for TLS. [Install by hand](https://docs.apimaker.dev/v4/docs/getting-started/install-by-hand.html) sets up each piece the way the installer does. ## Related - [Run on your computer](https://docs.apimaker.dev/v4/docs/getting-started/local-run.html) : API Maker Launchpad in detail · [How it works](https://docs.apimaker.dev/v4/docs/getting-started/how-it-works.html) · [API Maker configuration](https://docs.apimaker.dev/v4/docs/am-resources/api-maker-configurations.html) · [Deployment architectures](https://apimaker.dev/architectures) - [Next : your first API →](https://docs.apimaker.dev/v4/docs/getting-started/first-api.html) - [Run on your computer](https://docs.apimaker.dev/v4/docs/getting-started/local-run.html) --- # Install API Maker by Hand > Set up API Maker v4 on Ubuntu piece by piece, the way the install script does - the program, Docker, the network limits for many connections, MongoDB as a replica set, Redis, and the systemd service. Source: https://docs.apimaker.dev/v4/docs/getting-started/install-by-hand.html The [install script](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html) does all of this for you. Follow these steps when you need to know each piece, or to set up a server your own way. The pieces are ordinary : one program (`api_maker_be`, kept running by systemd), MongoDB as a replica set, Redis, and any reverse proxy for TLS. The [configuration](https://docs.apimaker.dev/v4/docs/am-resources/api-maker-configurations.html) page lists every setting of `.env` ; the MongoDB connection string goes in `am__mongo_db_connection`, Redis in `am__redisInternal` and `am__redisExternal`. The blocks below set up each piece the way the installer does, on Ubuntu as root. > **Example : API Maker v4** > > A release of API Maker for one processor is an npm package, read with `curl` (npm is not needed) : the server, the program of the sandboxes and the admin panel. > > ```bash > apt-get install -y curl jq > ARCH=$([ "$(uname -m)" = aarch64 ] && echo arm64 || echo x64) > PACKAGE=api-maker-engine-linux-$ARCH > VERSION=$(curl -fsSL "https://registry.npmjs.org/@sava-info-systems%2f$PACKAGE" | jq -r '."dist-tags".latest') > > mkdir -p ~/projects/api_maker/releases/$VERSION ~/projects/api_maker/uploads > curl -fsSL "https://registry.npmjs.org/@sava-info-systems/$PACKAGE/-/$PACKAGE-$VERSION.tgz" \ > | tar -xz --strip-components=1 -C ~/projects/api_maker/releases/$VERSION > ln -sfn ~/projects/api_maker/releases/$VERSION ~/projects/api_maker/current > ~/projects/api_maker/current/api_maker_be --version > ``` > **Example : Docker with Docker Compose** > > From the official apt repository of Docker, the commands the installer runs. They work on Ubuntu 20.04 to 26.04 ; a release too new for Docker's repository falls back to the one of 24.04 (`noble`). > > ```bash > for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do apt-get remove -y $pkg; done > apt-get update > apt-get install -y ca-certificates curl gnupg > install -m 0755 -d /etc/apt/keyrings > curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc > chmod a+r /etc/apt/keyrings/docker.asc > > CODENAME=$(. /etc/os-release && echo "$VERSION_CODENAME") > curl -fsL -o /dev/null "https://download.docker.com/linux/ubuntu/dists/$CODENAME/Release" || CODENAME=noble > echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $CODENAME stable" > /etc/apt/sources.list.d/docker.list > > apt-get update > apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin > docker compose version > ``` > **Example : Room for many connections** > > A server holds about 120 [WebSocket clients](https://docs.apimaker.dev/v4/docs/pages/web-socket-event-page.html#many-clients) for each MB of its memory (8.4 KB each, with its socket in the kernel and its subscription in Redis : [measured](https://docs.apimaker.dev/v4/docs/benchmarks/websockets/index.html)). Two limits of Linux end long before that, and the installer raises both : > > - **The table of the tracked connections.** A Linux server which runs Docker tracks every connection in a table (`nf_conntrack`), and a connection which closed stays in it for two minutes. Past the size of the table (262,144 connections by default) the kernel drops new connections without a word to the program which listens, SSH included. The installer gives it 256 connections for each MB of memory (between 131,072 and 16,777,216, never under what the server has already) : twice the clients the memory holds, so that clients which all come back after a restart find room while their old connections are still in it. A closed connection leaves it after 30 seconds, and its index gets a place for every four connections, so that a full table is looked through as fast as an empty one. An entry takes about 320 bytes, and only while its connection is there. > - **The open files.** Every connection is an open file of API Maker. The service may have as many as the table tracks (`LimitNOFILE`, 1,048,576 at the least), Caddy twice as many (it holds two for every client it passes on), and Linux gives a process no more than `fs.nr_open` (1,048,576 as it starts) : the installer raises it with them. With 1,048,576 open files a server of 16 GB took about a million clients, with half of its memory left. > > The queue of the connections which wait to be accepted gets longer too : the clients which all come back after a restart wait there. > > ```bash > MEMORY_MB=$(awk '/^MemTotal:/ { printf "%d", $2 / 1024 }' /proc/meminfo) > TRACKED=$((MEMORY_MB * 256)) > [ "$TRACKED" -lt 131072 ] && TRACKED=131072 > [ "$TRACKED" -gt 16777216 ] && TRACKED=16777216 > OPEN_FILES=$(( TRACKED > 1048576 ? TRACKED : 1048576 )) > > # The table is there at boot before its limits are read (Docker would load it later), with its index > modprobe nf_conntrack > echo nf_conntrack > /etc/modules-load.d/api-maker.conf > echo "options nf_conntrack hashsize=$((TRACKED / 4))" > /etc/modprobe.d/api-maker.conf > echo $((TRACKED / 4)) > /sys/module/nf_conntrack/parameters/hashsize > > cat > /etc/sysctl.d/90-api-maker.conf < net.netfilter.nf_conntrack_max = $TRACKED > net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30 > net.core.somaxconn = 16384 > net.ipv4.tcp_max_syn_backlog = 16384 > fs.nr_open = $((OPEN_FILES * 2)) > EOF > sysctl -p /etc/sysctl.d/90-api-maker.conf > > # The services : LimitNOFILE=$OPEN_FILES in api_maker_be.service, twice that in the one of Caddy > systemctl show api_maker_be -p LimitNOFILE > > sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max # how many are tracked now, and at most > dmesg | grep 'nf_conntrack: table full' # nothing : no connection was dropped > ``` > > API Maker reads the size of the table and its own open files when it starts, says in its log how many WebSockets it takes at the most, and warns when the table holds fewer connections than the server takes and than its memory has room for. > > One limit of the network is not set here, because API Maker keeps it itself while it runs : the memory Linux gives all its TCP connections together (`net.ipv4.tcp_mem`). The service runs as root and raises it as its connections come, two pages for each of them, never above a quarter of the memory of the server ([`tcpMemoryPercent`](https://docs.apimaker.dev/v4/docs/am-resources/api-maker-configurations.html)). Started as another user, it says in its log the line to run as root once it has that many connections : > > ```bash > sysctl net.ipv4.tcp_mem # three numbers of pages : nothing held back, pressure, the most > ``` > **Example : MongoDB as a one node replica set** > > API Maker needs MongoDB as a replica set : transactions only work there. A replica set with authentication needs a key file. > > ```bash > mkdir -p ~/config && cd ~/config > openssl rand -base64 756 > keyfile > chmod 600 keyfile && chown 999:999 keyfile > ``` > > **~/config/mongodb_api_maker.yml** > > ```yaml > services: > am_mongodb: > image: mongo:8.0.10 > restart: always > container_name: mongodb_api_maker > command: [ "--replSet", "rs0", "--bind_ip_all", "--port", "27017", "--keyFile", "/opt/keyfile" ] > ports: > - 38248:27017 > environment: > - MONGO_INITDB_ROOT_USERNAME=api_maker_user # 👈 your user > - MONGO_INITDB_ROOT_PASSWORD=CHANGE_ME # 👈 your password > - MONGO_REPLICA_SET_NAME=rs0 > healthcheck: > # Starts the replica set on the first run. > test: echo "try { rs.status() } catch (err) { rs.initiate({_id:'rs0',members:[{_id:0,host:'127.0.0.1:27017'}]}) }" | mongosh -u "api_maker_user" -p "CHANGE_ME" --port 27017 --quiet > interval: 10s > timeout: 30s > start_period: 5s > retries: 10 > volumes: > - ~/docker-data/mongodb_api_maker/data:/data/db > - ~/docker-data/mongodb_api_maker/configdb:/data/configdb > - ./keyfile:/opt/keyfile > ``` > > ```bash > docker compose --project-name api_maker -f ~/config/mongodb_api_maker.yml up -d > ``` > > **am__mongo_db_connection** > > ```text > mongodb://api_maker_user:CHANGE_ME@127.0.0.1:38248/api_maker_db?authSource=admin&replicaSet=rs0&directConnection=true > ``` > > MongoDB Compass, Studio 3T or any other client connects with the same string. > **Example : Redis** > > **~/config/redis_api_maker.yml** > > ```yaml > services: > redis_api_maker: > image: 'redis:7.0.5-alpine' > restart: always > container_name: redis_api_maker > ports: > - '7479:6379' > command: redis-server --loglevel warning --requirepass CHANGE_ME # 👈 your password > volumes: > - ~/docker-data/redis_api_maker:/data > logging: > driver: "json-file" > options: > max-size: "5m" > max-file: "3" > ``` > > ```bash > docker compose --project-name api_maker -f ~/config/redis_api_maker.yml up -d > ``` > > **am__redisInternal and am__redisExternal** > > ```text > {"nodes": [{port: 7479, host: "127.0.0.1", pass: "CHANGE_ME"}]} > ``` > **Example : API Maker as a systemd service** > > systemd starts API Maker when the server boots, and again whenever it stops. One process uses every core of the server. > > **~/config/.env (the settings the installer writes)** > > ```bash > BE_HOST_PORT="http://203.0.113.10:38246" # 👈 where the admin panel reaches API Maker, its web sockets too > am__serverName=primary > am__logFilePath=/root/logs/api_maker_be.txt > am__port=38246 > am__adminPanel__folder="/root/projects/api_maker/current/admin-panel" > am__adminPanel__port=4626 > am__oracleClientPath=/opt/oracle/instantclient > am__mongo_db_connection="mongodb://api_maker_user:CHANGE_ME@127.0.0.1:38248/api_maker_db?authSource=admin&replicaSet=rs0&directConnection=true" > am__redisInternal='{"nodes": [{port:7479, host:"127.0.0.1", pass: "CHANGE_ME"}]}' > am__passCommunication="…" # 👈 20 characters or more > am__passJWT="…" # 👈 32 characters or more : API Maker warns at every start under 32 > am__passDBEncryptDecrypt="…" # 👈 32 characters > ``` > > **/etc/systemd/system/api_maker_be.service** > > ```ini > [Unit] > Description=API Maker > Wants=network-online.target > After=network-online.target docker.service > # It never gives up : a database that is down for a while must not leave API Maker stopped. > StartLimitIntervalSec=0 > > [Service] > Type=exec > User=root > WorkingDirectory=/root/projects/api_maker > ExecStart=/root/projects/api_maker/current/api_maker_be --appRoot=/root/projects/api_maker --envPath=/root/config/.env > StandardOutput=append:/root/logs/api_maker_be.txt > StandardError=append:/root/logs/api_maker_be.txt > Restart=always > RestartSec=1s > # SIGTERM : the requests in flight finish, the clients of the web sockets are taken out of Redis and closed, the logs > # are written, the schedulers go to the other servers. The process gives that a minute at the most : it is killed > # after 90 seconds. > KillMode=mixed > TimeoutStopSec=90s > LimitNOFILE=1048576 > > [Install] > WantedBy=multi-user.target > ``` > > ```bash > mkdir -p ~/logs > systemctl daemon-reload > systemctl enable --now api_maker_be > > systemctl status api_maker_be # active (running) > tail -f ~/logs/api_maker_be.txt # what API Maker prints > curl -s http://127.0.0.1:38246/ | head -5 # the page of the process > ``` > > The installer also rotates the log past 50 MB with `logrotate`, run by the timer `api_maker_logrotate`. ## Related - [Install on a server](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html) · [API Maker configuration](https://docs.apimaker.dev/v4/docs/am-resources/api-maker-configurations.html) --- # Run API Maker on Your Computer > API Maker Launchpad is a desktop app for macOS, Windows and Linux which runs API Maker and its databases in Docker on your machine, adds databases in a few clicks, syncs your code with your editor, and can install API Maker on your own servers in its Cloud mode. Source: https://docs.apimaker.dev/v4/docs/getting-started/local-run.html A local API Maker is the place to build and test APIs before they reach a server : your own admin panel, your own databases, and your code in your editor. **API Maker Launchpad** is the desktop app which sets it up. Pick a folder and a version, click Start, and it downloads API Maker v4 from npm (one native program, no Node.js), starts the MongoDB and Redis API Maker needs in Docker, runs the admin panel and shows you the URLs and the sign-in details. It is free on your computer. **macOS** 13 Ventura or later · Apple silicon and Intel Universal · [Disk image **.dmg**](https://images.apimaker.dev/prod/api_maker_launchpad/API-Maker-Launchpad-1.0.0-macos-universal.dmg) · [Zip **.zip**](https://images.apimaker.dev/prod/api_maker_launchpad/API-Maker-Launchpad-1.0.0-macos-universal.zip) Open the .dmg and drag the app to Applications. **Windows** Windows 10 and 11 x64 · [Installer **.exe**](https://images.apimaker.dev/prod/api_maker_launchpad/API-Maker-Launchpad-1.0.0-windows-amd64-setup.exe) · [Portable **.zip**](https://images.apimaker.dev/prod/api_maker_launchpad/API-Maker-Launchpad-1.0.0-windows-amd64.zip) ARM64 · [Installer **.exe**](https://images.apimaker.dev/prod/api_maker_launchpad/API-Maker-Launchpad-1.0.0-windows-arm64-setup.exe) · [Portable **.zip**](https://images.apimaker.dev/prod/api_maker_launchpad/API-Maker-Launchpad-1.0.0-windows-arm64.zip) Installs for your user, no administrator rights needed. **Linux** Ubuntu 22.04+, Debian 12+, Fedora 39+ x64 · [Debian, Ubuntu **.deb**](https://images.apimaker.dev/prod/api_maker_launchpad/api-maker-launchpad_1.0.0_amd64.deb) · [Any distro **.tar.gz**](https://images.apimaker.dev/prod/api_maker_launchpad/API-Maker-Launchpad-1.0.0-linux-amd64.tar.gz) ARM64 · [Debian, Ubuntu **.deb**](https://images.apimaker.dev/prod/api_maker_launchpad/api-maker-launchpad_1.0.0_arm64.deb) · [Any distro **.tar.gz**](https://images.apimaker.dev/prod/api_maker_launchpad/API-Maker-Launchpad-1.0.0-linux-arm64.tar.gz) Needs GTK 3 and WebKitGTK 4.1 ; the .deb installs them. Version 1.0.0 · the SHA-256 checksum of every file and the install steps are on [apimaker.dev/download](https://apimaker.dev/download) > Diagram : API Maker Launchpad : one folder, Docker for the databases, API Maker and its admin panel on your computer > > API Maker Launchpad on your computer : the desktop app picks a folder, downloads Node.js and API Maker from npm, starts MongoDB and Redis and your extra databases in Docker, runs API Maker with its admin panel, and keeps a folder in sync with your editor through the local client. ## What it does - **Installs and starts everything** : API Maker v4 from npm, only the package of your computer, checked against the integrity npm publishes ; MongoDB as a replica set and Redis in Docker ; the admin panel, served by API Maker itself. - **Adds databases in a few clicks** : MongoDB, PostgreSQL, MySQL, MariaDB, SQL Server, Oracle, TiDB and Percona Server, several of each if you want, every one with its connection string shown. **Create instance** puts the credentials in the default secret and creates the instance in API Maker. - **Runs several projects at once**, each in its own folder and on its own ports. - **Keeps a folder in sync with your editor** through the local client (see below). - **Stops everything it started** when you close it, and cleans up after a crash. - **Deletes a project** with everything it created, after you confirm by typing its name. ## Requirements | | | |---|---| | Docker | Docker Desktop, OrbStack, Rancher Desktop, Colima or Docker Engine, with Docker Compose v2 | | macOS | 13 Ventura or later, Intel or Apple silicon | | Windows | 10 or 11, x64 or ARM64 | | Linux | x64 or ARM64 with GTK 3 and WebKitGTK 4.1 (Ubuntu 22.04+, Debian 12+, Fedora 39+…) | | Memory | about 4 GB free for API Maker, MongoDB and Redis ; each extra database needs more | ## First run 1. **Pick a folder** An empty folder becomes a new workspace ; a folder which already has one is loaded from its `.api_maker_launchpad_state` file. Recent folders are listed on the welcome screen. 2. **Set it up** Choose the project name, the API Maker version (the list comes from npm), the license key and the ports. Ports already in use are flagged before anything starts. 3. **Start** The progress shows step by step, with the logs of every service next to it. When it is done, the admin panel opens in your browser. 4. **Add a database** On the **Databases** page, pick the engine and version, set the port, password, user and database name, and click **Create instance**. The instance is ready in API Maker with its connection string in the default secret. 5. **Call your first API** Follow [Your first API](https://docs.apimaker.dev/v4/docs/getting-started/first-api.html) with the URL the app shows. ## Ports and folder The app keeps everything in the folder you picked : the API Maker install, its configuration (`config/.env`, `config/docker-compose.yml`), the logs and the data files of every database (`docker-data/…`). Docker only runs the containers ; no data lives inside them. | Service | Default port | |---|---| | API Maker : its APIs and its WebSockets | 38246 | | Admin panel | 4626 | | Internal MongoDB | 38248 | | Internal Redis | 7479 | | Extra databases | MongoDB 27018 · PostgreSQL 5433 · MySQL 3307 · MariaDB 3308 · Percona 3309 · TiDB 4001 · SQL Server 14330 · Oracle 1522 | New projects get free ports. Services bind to `127.0.0.1` on macOS and Windows and to `0.0.0.0` on Linux ; the bind address is a project setting. ## The license key Launchpad sets the key `____your_license_key____` for you : it is for development on your computer, it is free, and it is never sent to the licence server (the licence page of the admin panel shows `LOCAL`). A server which serves other people needs a licence key of its own : set it in **Project Settings** or in the admin panel. For a key, write to [contact@apimaker.dev](mailto:contact@apimaker.dev). [What the licence check sends](https://docs.apimaker.dev/v4/docs/security/overview.html#licence-check). ## Your code in your editor : the Local Client The **Local Client** page of a project keeps a folder of your computer in sync with API Maker, both ways : edit custom APIs, utility classes, schemas, schedulers, hooks and test cases in VS Code, WebStorm, Zed or any editor, and what you save in the admin panel lands on the disk. It runs the local client which ships with API Maker (`npm run start` in the folder), started and watched by the app. - **Where the code is kept** : a Git repository on this computer (recommended, made by the app and served to API Maker on `127.0.0.1`), GitHub, GitLab or another host with a personal access token, or just a folder without Git. - Every folder has a card with the state of the sync, the Git branch, and **Open in** buttons for the editors found on your computer. - The folder is an ordinary local client folder : `npm run test` runs the [test cases](https://docs.apimaker.dev/v4/docs/test-cases/test-cases.html) of the account from the terminal and writes their coverage for your IDE, and an AI agent working in the folder finds the [security report](https://docs.apimaker.dev/v4/docs/apis-security/api-security-report.html), every item of the account as files and the [`AGENTS.md`](https://docs.apimaker.dev/v4/docs/ai/llms.html#agents-md) guide every commit writes. See [Developer tools](https://docs.apimaker.dev/v4/docs/features/developer-tools.html#your-own-editor) for the local client on a server. ## Languages for native APIs Custom APIs, hooks, schedulers and event listeners marked **Run on native process** run on the machine of API Maker instead of a sandbox, with the program of their language API Maker finds first on its PATH ([Native process](https://docs.apimaker.dev/v4/docs/apis-all/custom-apis/user-created-custom-api.html#native-process)). The app sets those languages up for you : the **Languages** page of a project shows one card per language. The setup of a new project asks none, so its code runs in the sandboxes until you choose some. - **What your computer has is found first** : the PATH, Homebrew, nvm, Volta, fnm, asdf, mise, pyenv, uv, rustup, SDKMAN, the installers of Go, .NET and the JDKs. Each one says its version and whether API Maker runs code on it ; **Use them** picks every one that works, and nothing is installed for them. - **Or a version the app installs**, listed live from its publisher : nodejs.org, the releases of Bun, python-build-standalone, static-php-cli and windows.php.net, go.dev, static.rust-lang.org, the releases of .NET, Eclipse Temurin and the releases of Kotlin. Only the [versions API Maker runs](https://docs.apimaker.dev/v4/docs/languages/index.html#versions) are offered, the recommended one first. Each card says what a version downloads and takes on the disk. - **Checked and kept apart** : a download must match the checksum its publisher gives, and each program says its version before it is used. Every version goes into one folder shared by your projects (`~/.api-maker-launchpad/languages`, which App Settings moves) : nothing is installed in the system and no shell profile changes. - **Only API Maker sees them** : their folders go first on the PATH of API Maker and its runners, with `JAVA_HOME`, `DOTNET_ROOT` and the like. The next start installs what is missing, or **Install now** does. - **Full Docker** projects get the Linux builds, mounted into the container of API Maker ; PHP and the C compiler Go and Rust need come with its image. | Language | Program | Note | |---|---|---| | Node.js, Bun | `node`, `bun` | | | Python | `python3` | 3.12 or later | | PHP | `php` | with FFI, the `g.sys` calls are answered in its runner | | Go, Rust | `go`, `cargo` | need a C compiler (Xcode Command Line Tools, `gcc`) ; Go does not run native code on Windows | | C# | `dotnet` (the SDK) | | | Java, Kotlin | `java` (a JDK), `kotlinc` | Kotlin runs on the JDK | ## Cloud mode The **Cloud** tab installs API Maker on servers you rent anywhere, and everything it needs : its MongoDB and Redis, a reverse proxy (Caddy, Ferron or Pingap) with Let's Encrypt certificates, your databases with their replication, and the firewall. Everything happens over SSH from your computer : no agent, no third party service. - **Servers** : Ubuntu 24.04 LTS, x86-64 or ARM64, 1 core, 900 MB of memory and 10 GB of disk at least (4 GB and 20 GB recommended). Sign in as root or a sudo user with a password, a key or your SSH agent. Credentials are stored encrypted on your computer, the key in the keychain of the operating system. - **Environments and architectures** : a project groups environments (production, staging…), each one an API Maker with its own servers, version and license key. Start from a layout (all in one, app + data, dedicated databases, load balanced) and drag components between servers on the diagram. - **Databases** : MongoDB replica sets, PostgreSQL with streaming replicas, MySQL and Percona with replicas, MariaDB replicas or Galera, SQL Server, Oracle and TiDB, with password rotation and moves between servers with their data. - **Languages for native APIs** : choose them once in the **Languages** tab of an environment ; every API Maker server gets them, those added later too, from their publishers into `/root/languages`, or uses the ones Ubuntu has. A new environment starts with the languages chosen last. The page of a server lists what it has and installs a language on it at once. - **Day two** : deploy new versions, rolling updates behind the load balancer, live logs and health of every server, and a full uninstall. - **A server with PM2** : when PM2 already runs API Maker on a server, the review of the deployment asks **Switch to systemd** (recommended) or **Keep PM2** ; whatever else PM2 runs stays. - **Security** : the SSH host key of a server is pinned on the first connection, and every credential is stored encrypted on your computer. [Install on a server](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html#architectures) maps the [reference architectures](https://apimaker.dev/architectures) of the website to the layouts of Cloud mode. The install script on the same page sets up one server from its own terminal instead. - [Next : your first API →](https://docs.apimaker.dev/v4/docs/getting-started/first-api.html) - [Install on a server](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html) --- # Upgrade from API Maker v3 > Move a server of API Maker v3 (the Node.js edition) to v4 - with the V3 to V4 Migration page of API Maker Launchpad, which rolls back on failure, or with the install script - what stays, what changes for your code, and what to check after. Source: https://docs.apimaker.dev/v4/docs/getting-started/upgrade-from-v3.html API Maker v4 takes over a server of v3 in place : the same MongoDB and Redis with their data, the same secrets, the same license key, and your Git repositories pull into v4. Your APIs keep their URLs. Two ways to do it : | | [Launchpad : V3 to V4 Migration](https://docs.apimaker.dev/v4/docs/getting-started/upgrade-from-v3.html#with-api-maker-launchpad) | [The install script](https://docs.apimaker.dev/v4/docs/getting-started/upgrade-from-v3.html#with-the-install-script) | |---|---|---| | Where you run it | The desktop app, over SSH | A terminal on the server | | Checks the server first | yes, and says what blocks the move | no | | Rolls back on failure | yes, the data of MongoDB included | no : keep a backup | | Afterwards | The server is an environment of Launchpad : health, statistics, logs, terminals | A server like any other installed by the script | ## Before you start - **Take a backup** of the MongoDB of API Maker (`mongodump`) and of `/root/config/.env`. The Launchpad page takes one itself ; the install script does not. - **Try it on a copy first** when the server is in production : a snapshot of the server, restored on a new one, is the simplest copy. - **Read the breaking changes** of [v4.0.0](https://docs.apimaker.dev/v4/docs/blog/release-notes/v4.0.0.html) : a few queries match differently (`null` and `$like` on SQL and MongoDB), and a value starting with `__:` is no longer SQL. - **A server which runs alone.** The Launchpad page refuses a secondary server of v3, and a server whose Caddy spreads the requests over other servers, and says so. ## With API Maker Launchpad **V3 to V4 Migration**, in the sidebar of the Cloud mode of [API Maker Launchpad](https://docs.apimaker.dev/v4/docs/getting-started/local-run.html#cloud-mode), moves a server installed with the v3 install script. 1. **Check** Pick the server, or add it with its SSH sign-in. The page reads it without changing anything : the version of v3 and what runs it (PM2 or systemd), `.env`, MongoDB with its databases and size, Redis, Caddy, the license, the free disk space. What prevents the move is said, with what to do. 2. **Destination** Choose a project and an environment of Launchpad, new or empty, and the version of API Maker v4. 3. **Review** Every step, the lines of `.env` which change, the Caddyfile before and after, and the checks at the end. Confirm by typing the name of the server. 4. **Watch it run** The migration runs on the server itself : closing the app or losing the connection does not stop it, and the log follows live. **Stop** rolls back. What the migration does, in order : 1. Downloads API Maker v4 next to v3, checks it against npm and runs it once, while v3 keeps serving. 2. Saves what v3 runs with (`.env`, the Caddyfile, the services, the list of PM2) in `/root/backups/api_maker_v3_to_v4/`. 3. Stops v3, then saves the data of MongoDB with `mongodump` while nothing writes to it. 4. Keeps v3 in `/root/projects/sava_api_maker_v3`, puts v4 in `/root/projects/sava_api_maker` with the `license.txt` and the uploaded files of v3. 5. Writes `.env` for v4, runs v4 with systemd, and points Caddy at it : the same addresses and certificates. 6. Checks v4 the way your apps reach it : an API, the WebSockets and the admin panel, through Caddy. **When a step fails, or you press Stop, everything goes back as it was** : Caddy, the services, the folders, `.env`, and the data of MongoDB when v4 had started. Then v3 starts again. The folder of v3 and the backup stay on the server until you delete them. ## With the install script On the server of v3, run the [install command](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html#install-with-one-command) of v4 and answer **no** when it asks to re-install MongoDB and Redis. - v4 takes the place of the service `api_maker_be`, with the same MongoDB, Redis and secrets. The uploaded files and the license file are copied. - The folder of v3, `~/projects/sava_api_maker`, is left as it was. - The service `api_maker_fe` goes : API Maker serves the admin panel itself. ## What changes for your apps - **WebSockets** move to the port of the APIs : a client which reached `:38245` directly connects to `:38246`. Behind Caddy, the addresses stay what they were. - **The admin panel** is served by API Maker on port `4626`, or through Caddy as before. - **Tokens** of API users and of your users keep working : v4 reads the same secrets. ## What changes for your code - **Packages.** A sandbox of v4 has only the packages its account lists in [Sandbox settings](https://docs.apimaker.dev/v4/docs/settings/sandboxSettings.html#packages). The packages v3 had built in (`lodash`, `moment`…) are added to the list of an account of v3 by the first start of v4. - **Removed features.** UI Maker, the API Maker store, third party APIs and notes are gone. A Git pull lists what it skipped ; the utility classes third party APIs brought stay in the account, with their packages. - **Queries.** `null` in `find` on SQL means `IS NULL`, `$like` on MongoDB is the pattern of SQL, and `__:` values are plain values : see the [breaking changes](https://docs.apimaker.dev/v4/docs/blog/release-notes/v4.0.0.html). - **Languages.** Your TypeScript and JavaScript run as before. New code can be written in [seven more languages](https://docs.apimaker.dev/v4/docs/languages/index.html). ## After the move - Open the admin panel and run the [security report](https://docs.apimaker.dev/v4/docs/apis-security/api-security-report.html) : it reads the hooks and groups of v3 and says where rows are open. - Run your [test cases](https://docs.apimaker.dev/v4/docs/test-cases/test-cases.html), or call the APIs your apps use most. - Go through [Before you go live](https://docs.apimaker.dev/v4/docs/security/go-live.html). - Delete the folder of v3 and the backup once you are sure. ## Related - [Install on a server](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html) · [Run on your computer](https://docs.apimaker.dev/v4/docs/getting-started/local-run.html) · [Release notes of v4.0.0](https://docs.apimaker.dev/v4/docs/blog/release-notes/v4.0.0.html) --- # Your First API in 10 Minutes > A hands-on start with the sample shop every new API Maker account has - connect MongoDB, get a token, save a category and a product through the schema APIs, read them back with filters and deep populate, see a validation error, and check the account with the security report. Source: https://docs.apimaker.dev/v4/docs/getting-started/first-api.html Every new admin or developer account of API Maker comes with a **sample shop** : an instance named `mongodb`, a database `shop` with the schemas of `categories`, `customers`, `products`, `orders` and `orderItems`, custom APIs under `/default/…`, hooks, an event, a migration script and a utility class. This page uses it, so you only need a MongoDB to point it at. > **Tip : Nothing installed yet ?** > > [Install on a server](https://docs.apimaker.dev/v4/docs/getting-started/install-on-server.html) with one command, or [run API Maker on your computer](https://docs.apimaker.dev/v4/docs/getting-started/local-run.html) with the desktop app. Both print the URL of the admin panel and the sign-in details. The defaults of the install script are `admin@admin.com` / `Admin_123456789`. In the commands below, `$AM` is the URL of your API Maker (`http://127.0.0.1:38246`, or the domain of your server) and `admin` is the user path of the account. ## 1. Point the sample instance at a MongoDB 1. **Open the default secret** Admin panel → **Security → Secret Management** → the secret named `Default`. It is TypeScript : a `common` object with keys, connection strings and the passwords of API users. 2. **Set `common.connectionString.mongodb`** The sample instance reads its connection string from that path. Paste the string of any MongoDB you can reach (the MongoDB of API Maker Launchpad, a MongoDB Atlas cluster, the one the install script created : it is in `/root/config/.env`). Save. ```typescript connectionString: { mongodb: 'mongodb://user:password@127.0.0.1:27017/?authSource=admin&replicaSet=rs0&directConnection=true', // ... }, ``` 3. **Check the instance** **APIs & Logic → Instance API (DB API)** → instance `mongodb` → **Test Instance**. The database `shop` appears in the list after the first save below : MongoDB creates databases and collections on first write. ## 2. Get a token The account has an API user named `default`. Its password is the value of `common.apiUserPasswords.default` in the secret : `12345` until you change it. ```bash curl -s -X POST "$AM/api/system-api/admin/token" \ -H "Content-Type: application/json" \ -d '{ "u": "default", "p": "12345" }' ``` ```json { "success": true, "statusCode": 200, "data": { "token": "eyJhbGciOi…", "refresh_token": "eyJhbGciOi…", "expires_in": 259200 } } ``` Keep the token in a variable : `TOKEN=eyJhbGciOi…`. Every call below sends it in `x-am-authorization`. The group `Default` of this API user allows every API, which is fine for a first try and wrong for production : see [Handle role based permissions](https://docs.apimaker.dev/v4/docs/authorization/handle-role-based-permissions.html) and [Before you go live](https://docs.apimaker.dev/v4/docs/security/go-live.html). ## 3. Save a category, then a product The product schema needs a `category` (a relation to `categories._id`), a `currency` from `IN`, `US` or `GB`, and a `price_cents`. So the category comes first. ```bash curl -s -X POST "$AM/api/schema/admin/mongodb/shop/categories/save-single-or-multiple" \ -H "Content-Type: application/json" -H "x-am-authorization: $TOKEN" \ -d '{ "name": "Accessories" }' ``` ```json { "success": true, "statusCode": 201, "data": { "_id": "66fa1c2d9b1e4a0012a3c001", "name": "Accessories", "slug": "accessories" } } ``` The `_id` was generated by API Maker (`isAutoGenerateByAM`) and the `slug` by the `conversionFun` of the schema. Now the product : ```bash curl -s -X POST "$AM/api/schema/admin/mongodb/shop/products/save-single-or-multiple" \ -H "Content-Type: application/json" -H "x-am-authorization: $TOKEN" \ -d '{ "name": " Wireless Mouse ", "currency": "in", "price_cents": 129900, "category": "66fa1c2d9b1e4a0012a3c001" }' ``` ```json { "success": true, "statusCode": 201, "data": { "_id": "66fa1c9a9b1e4a0012a3c002", "public_id": "01J8Z3C9F2X4Q7N8V1M6K5R0TA", "product_no": 1000, "name": "Wireless Mouse", "slug": "wireless-mouse", "status": "DRAFT", "currency": "IN", "price_cents": 129900, "is_active": true, "created_at": "2026-09-30T10:15:22.418Z", "updated_at": "2026-09-30T10:15:22.418Z", "category": "66fa1c2d9b1e4a0012a3c001" } } ``` Look at what the schema did : the name was trimmed, `currency` upper-cased, `status` and `is_active` got their defaults, `created_at` its default function, `product_no` the next number of its auto increment, `public_id` a ULID, `slug` a value computed from the name. That is the [schema pipeline](https://docs.apimaker.dev/v4/docs/schema/schema.html) ; the generated APIs under `/api/gen` would have stored the body as it came. ## 4. Read it back Get all products, only some fields, with the category populated from its relation : ```bash curl -s "$AM/api/schema/admin/mongodb/shop/products?select=name,slug,price_cents,category&deep=[{s_key:'category'}]" \ -H "x-am-authorization: $TOKEN" ``` ```json { "success": true, "statusCode": 200, "data": [ { "_id": "66fa1c9a9b1e4a0012a3c002", "name": "Wireless Mouse", "slug": "wireless-mouse", "price_cents": 129900, "category": { "_id": "66fa1c2d9b1e4a0012a3c001", "name": "Accessories", "slug": "accessories" } } ] } ``` `deep` only needed the source key : the target table and key come from the schema. The same filters work as query params on get all, or in the body of the query API : ```bash curl -s -X POST "$AM/api/schema/admin/mongodb/shop/products/query" \ -H "Content-Type: application/json" -H "x-am-authorization: $TOKEN" \ -d '{ "find": { "status": "DRAFT", "price_cents": { "$gte": 100000 } }, "sort": "-created_at", "limit": 10, "getTotalCount": true }' ``` ## 5. See a refusal Send a product that breaks three rules at once : ```bash curl -s -X POST "$AM/api/schema/admin/mongodb/shop/products/save-single-or-multiple" \ -H "Content-Type: application/json" -H "x-am-authorization: $TOKEN" \ -d '{ "name": "M", "currency": "EUR", "price_cents": -5, "category": "66fa1c2d9b1e4a0012a3c001", "discount_pct": 10 }' ``` ```json { "success": false, "statusCode": 400, "errors": [ { "type": "minLength", "field": "name", "message": "Property 'name' should have minimum length of '2'.", "code": 400 }, { "type": "enumValidation", "field": "currency", "message": "Property 'currency' should have any value from [IN, US, GB].", "code": 400 }, { "type": "min", "field": "price_cents", "message": "Please provide minimum '0' for 'price_cents' field.", "code": 400 }, { "type": "invalidValue", "field": "discount_pct", "message": "A discount requires approved_by.", "code": 400 } ] } ``` Every problem is reported in one reply, including the message thrown by the `validatorFun` of `discount_pct`, and nothing was saved. The messages can be translated per caller with [internationalization](https://docs.apimaker.dev/v4/docs/i18/i18.html). ## 6. Try the rest of the sample - **API testing page** (`APIs & Logic → API Testing`) : pick the instance, the table and the API, get a sample payload, send it and read the response, then copy the call as code in 21 languages. - **Custom APIs** under `APIs & Logic → Custom API` : `/default/deep-populate-orders`, `/default/find-join-products`, `/default/caching-example`, `/default/ws-notify`, `/default/login`… Open one to read a complete, commented example of the feature. They have the access type `NO_ACCESS`, so they run from the testing page and from other code, not from outside, except the login and captcha ones. - **Hooks** : the instance, database and collection hooks of the sample show how a person is kept to their own rows. - **Schemas** of the five collections show every schema feature in use. ## 7. Check it with the security report Open **Security › APIs Security Report & Actions**. API Maker reads the settings and the code of the account, and gives it a score out of 100. - Each finding says what a person could reach, with the request which proves it. - Most findings have an action : see the change, then apply it. The account is scanned again right after. - The sample starts open for its first steps (the API user `default` and a group `Default` which grants everything) : the report tells you what that opens, and [Before you go live](https://docs.apimaker.dev/v4/docs/security/go-live.html) closes it. More in [APIs Security Report & Actions](https://docs.apimaker.dev/v4/docs/apis-security/api-security-report.html). ## Where to go next - [All APIs at a glance](https://docs.apimaker.dev/v4/docs/apis-all/overview.html) : Every operation of a table, with its method and URL. - [Table schema](https://docs.apimaker.dev/v4/docs/schema/schema.html) : Write the schema of your own tables. - [Custom APIs](https://docs.apimaker.dev/v4/docs/apis-all/custom-apis/user-created-custom-api.html) : Your first function behind a URL, in the language you like. - [Before you go live](https://docs.apimaker.dev/v4/docs/security/go-live.html) : Default passwords, the Default group, the row gate, HTTPS and backups. --- # API Maker Cheat Sheet > The URLs, headers, query params, schema options and g object of API Maker on one page - keep it next to your editor. Source: https://docs.apimaker.dev/v4/docs/cheat-sheet.html ## URLs ```text /api/schema////
[/operation] schema APIs (apply the schema) /api/gen////
[/operation] generated APIs (schemaless) /api/custom-api// custom APIs /api/system-api// system APIs (always POST) :: a tenant of a multi-tenant instance ``` | Operation | Method and path suffix | |---|---| | Get all · get all by stream | `GET /` · `GET /stream` | | Get by id | `GET /get-by-id/:id[/:primaryKey]` | | Save · master save | `POST /save-single-or-multiple` · `POST /master-save` | | Update by id · update many · replace by id (MongoDB) | `PUT /update-by-id/:id[/:primaryKey]` · `PUT /update-many` · `PUT /replace-by-id/:id[/:primaryKey]` | | Array operations (MongoDB) | `PUT /array-operations` | | Remove by id · remove by query | `DELETE /:id[/:primaryKey]` · `POST /query/delete` | | Query · query by stream | `POST /query` · `POST /query-stream` | | Count · aggregate (MongoDB) | `POST /count` · `POST /aggregate` | | Distinct · distinct with query | `GET /distinct/:field[/:order]` · `POST /distinct/:field[/:order]` | ## Headers | Header | Values | |---|---| | `x-am-authorization` | token of the API user (the application) | | `x-am-user-authorization` · `x-google-authorization` · `x-azure-authorization` · `x-aws-authorization` · `x-custom-authorization` | token of the person, from an auth provider | | `x-am-response-case` | `noChange` `camelCase` `capitalCase` `constantCase` `dotCase` `headerCase` `noCase` `paramCase` `pascalCase` `pathCase` `sentenceCase` `snakeCase` | | `x-am-content-type-response` | `application/json` `text/xml` `text/yaml` `text/plain` `text/html` `application/octet-stream` | | `x-am-response-object-type` | `no_action` `make_flat` | | `x-am-meta` | `true` : execution time, plan, groups, sandbox in `meta` | | `x-am-cache-control` | `no_action` `reset_cache` | | `x-am-get-encrypted-data` | `no_encryption` `get_only_encryption` `get_data_and_encryption` | | `x-am-encrypted-payload` | `true` when the body is `{ dataEncFE }` | | `x-am-internationalization` | name of a language of i18N Management | | `x-am-tenant-username` | tenant of a multi-tenant instance | | `x-am-sandbox-timeout` | milliseconds, default 13000 | | `x-am-run-in-sandbox` | `0` any, `1` one sandbox, `n` first n | | `x-no-compression` | `true` | ## Query params (get all, get by id, streams ; in the body for the query APIs) ```text ?find={status:'ACTIVE',price:{$gte:100}} JSON5, every MongoDB operator : $eq $ne $gt $gte $lt $lte $in $nin $and $or $nor $not $exists $regex $mod $expr ... + $like $isNull ?select=name,price ?select=-password include, or exclude with - ?sort=-created_at,name - for descending ?skip=20&limit=10 paging ?getTotalCount=true totalCount in the reply ?deep=[{s_key:'category'}] related rows, from the schema relation or with t_instance t_db t_col t_key find select isMultiple limit skip sort deep ?customer_id=42 ?price>=100 ?name=Bob,Alice any column as a filter ?find={'owner.customer_id':42} find and join : a field of a related table ?upsert=true ?returnDocument=before update by id ?throwErrorIfRecordNotFound=true update by id, replace by id, remove by id : 400 instead of null when the id is unknown ``` ## Response ```json { "success": true, "statusCode": 200, "data": [], "totalCount": 5, "warnings": [], "logs": [], "meta": {} } { "success": false, "statusCode": 400, "errors": [ { "type": "required", "field": "name", "message": "…", "code": 400 } ] } ``` ## Schema ```typescript name: { __type: EType.string, // string number boolean date objectId file files, [EType.string] for arrays, a nested object for objects isPrimaryKey: true, isAutoGenerateByAM: { valueGeneratorType: 'ObjectID' | 'GUID_UUID' | 'ULID' | 'ShortUUID' }, isAutoIncrementByAM: { start: 1000, step: 1 }, // or true isAutoIncrementByDB: true, isConcurrencyControlField: true, // version field of optimistic concurrency control validations: { required, min, max, minLength, maxLength, email, enum: [], validatorFun: (value, all) => true }, conversions: { trim, trimStart, trimEnd, toLowerCase, toUpperCase, conversionFun: (value, all) => value, encryption, hashing, defaults: { defaultValue, defaultFun, shouldReplaceNullWithDefault, shouldReplaceEmptyStringWithDefault } }, instance: 'x', database: 'y', collection: 'z', column: '_id', // relation for deep, find and join, master save isVirtualField: true, s_columnVirtualLinker: '_id', t_columnVirtualLinker: 'product_id', // one to many } ``` ## The global object g **TypeScript** ```typescript g.req.body g.req.query g.req.params g.req.headers g.req.eventData g.req.auth.authAMUser .authAMDB .authGoogle .authAzure .authAWS .authCustom g.res.output g.res.statusCode g.res.contentType g.res.errors g.res.warnings g.res.shared g.sys.db.getAll({ instance, database, collection, queryParams, headers }) getAllByStream getById saveSingleOrMultiple masterSave arrayOperations updateById updateMany replaceById removeById query queryByStream removeByQuery aggregate count distinct distinctQuery g.sys.db.gen.getAllGen(…) the same, schemaless, with the Gen suffix g.sys.system.encrypt decrypt hash getToken callExternalApi executeQuery getSecret getTableMeta createIndexes dropIndexes getIndexes emitEvent emitEventWS isValidDataForTable isValidDataForCustomAPI multiTenantInstanceUpdated isValidConnectionString g.sys.cache.getKey setKey removeKey resetCacheDB resetCacheCustomApis resetCacheSystemApis g.logger.debug log info warn error g.res.shared.x = … travels with the request : pre hook → API → post hook g.shared.x = … lives as long as the runner, shared by the requests it serves await g.sys.db.count({ … }, true) second argument true : the whole envelope, no throw import * as utils from 'utils/MyClass' utility classes ``` ## Where things are in the admin panel | | | |---|---| | Instances, databases, tables, schemas, APIs | APIs & Logic → Instance API (DB API) | | Custom APIs · SSR websites · System APIs · Events · Schedulers · WebSocket events · Initializers · Utility classes · API testing · Test cases · Code finder · i18N · Generated interfaces · Swagger | APIs & Logic | | Security report · Groups · API users · Auth providers · Secrets · Vulnerabilities · Encrypt strings · Dev accounts | Security | | ER diagram · Index Maker · Database migration · Auto increments | Database | | Analytics · Log explorer · Servers · Redis · Git · Log profile · Native process logs · Sandbox settings · Deploy API Maker · Licenses | Operations | | Any page by its name | ⌘K (Ctrl K) | (The code of this page is also written in Python, PHP, C#, Go, Rust, Java, Kotlin : https://docs.apimaker.dev/v4/docs/cheat-sheet.md) --- # API Maker Docs for AI Assistants > How to give ChatGPT, Claude, Cursor, Copilot or any agent the API Maker documentation - llms.txt and llms-full.txt, the Markdown twin of every page, the AGENTS.md API Maker writes into your repository, and the security report an assistant can act on. Source: https://docs.apimaker.dev/v4/docs/ai/llms.html API Maker is built for the AI era, and so is this documentation. Every page is available as plain Markdown, an index lists them all for agents, and an assistant working in your project folder finds the code and the security report of your account as files. ## Files an assistant can read | What | URL | Use it for | |---|---|---| | Index of the documentation | [`https://docs.apimaker.dev/llms.txt`](https://docs.apimaker.dev/llms.txt) | One page per line with its title, description and Markdown URL, grouped like the navigation. Give it to an agent so it fetches only the pages it needs. | | The whole documentation | [`https://docs.apimaker.dev/llms-full.txt`](https://docs.apimaker.dev/llms-full.txt) | Every page in one text file, in reading order, with the code in TypeScript only and without the raw output of the benchmarks. Upload it to a tool which searches its files (a project knowledge base), or give an agent `llms.txt` and let it fetch the pages it needs. | | One part of it | [`llms-getting-started.txt`](https://docs.apimaker.dev/llms-getting-started.txt), [`llms-security.txt`](https://docs.apimaker.dev/llms-security.txt), [`llms-build.txt`](https://docs.apimaker.dev/llms-build.txt), [`llms-operate.txt`](https://docs.apimaker.dev/llms-operate.txt), [`llms-code-examples.txt`](https://docs.apimaker.dev/llms-code-examples.txt), [`llms-benchmarks.txt`](https://docs.apimaker.dev/llms-benchmarks.txt), [`llms-release-notes.txt`](https://docs.apimaker.dev/llms-release-notes.txt) | The pages of one tab of the navigation, the same way : a smaller file for an assistant which works on one part. | | Any page as Markdown | the page URL with `.md` instead of `.html`, for example [`/v4/docs/schema/schema.md`](https://docs.apimaker.dev/v4/docs/schema/schema.md) | Clean text without navigation, with the snippets resolved and the diagrams replaced by their caption. | | The website for AI | [`https://apimaker.dev/llms.txt`](https://apimaker.dev/llms.txt) and [`llms-full.txt`](https://apimaker.dev/llms-full.txt) | The feature pages and the deployment architectures. | Every page also carries `` pointing at its Markdown twin, and JSON-LD structured data, so crawlers and agents find the right version on their own. ## On every page The bar at the top of a page offers **Copy as Markdown** (the Markdown twin, ready to paste in a chat), **View Markdown**, and **Open in ChatGPT** or **Open in Claude**, which start a chat with the page already loaded. ## Prompts which work well **Ask about a feature** ```text Read https://docs.apimaker.dev/v4/docs/apis-all/query-params/deep.md and https://docs.apimaker.dev/v4/docs/schema/schema.md, then write the schema of my orders table so that a customer is populated from the customers table in another database. ``` **Write a custom API** ```text Using https://docs.apimaker.dev/v4/examples/custom-apis/custom-api.md and https://docs.apimaker.dev/v4/docs/pre-defined-terms/global-object-g.md, write a custom API for API Maker which returns the ten latest orders of the person in g.req.auth.authAMDB. ``` **Write a page of an SSR website** ```text Read https://docs.apimaker.dev/v4/docs/ssr/ai-guide.md and https://docs.apimaker.dev/v4/docs/ssr/data.md, then write pages/account/orders.tsx for my SSR website : the orders of the signed-in customer, newest first, 20 per page, and the rule of site.config.ts which keeps each customer to its own orders. ``` **Give an agent the whole documentation** ```text The documentation of the backend platform we use is at https://docs.apimaker.dev/llms.txt. Fetch the pages you need from it before answering questions about API Maker. ``` ## An assistant in your project folder With the [local client](https://docs.apimaker.dev/v4/docs/features/developer-tools.html#your-own-editor) (or the Local Client page of [API Maker Launchpad](https://docs.apimaker.dev/v4/docs/getting-started/local-run.html)), every item of the account is a file in a Git repository : `src/custom_apis/…`, `src/utility_classes/…`, `src/schemas/…`, hooks, events, schedulers, migrations, test cases, settings and the SSR websites (`src/ssr/…`). An agent such as Claude Code, Cursor or Copilot can read and change them ; the local client syncs what it saves to API Maker. - **The repository explains itself** : API Maker writes an [`AGENTS.md`](https://docs.apimaker.dev/v4/docs/ai/llms.html#agents-md) at its root, the guide an agent reads before it starts. - **Types come with the code** : `import * as T from 'types'` gives every interface of API Maker and `import * as db from 'db-interfaces'` the interfaces generated from your schemas, so an assistant writes typed code. - **Tests run from the terminal** : `npm run test` runs the [test cases](https://docs.apimaker.dev/v4/docs/test-cases/test-cases.html) of the account with their mocks and writes the coverage to `coverage/lcov.info`. - **The security report is in the repository** : `src/api_security_report/report.md` says where a person could read rows which are not theirs and how to fix it. It is kept fresh while the local client is connected, so an assistant can fix hooks, groups and settings and see the result on the next scan. See [APIs Security Report & Actions](https://docs.apimaker.dev/v4/docs/apis-security/api-security-report.html#in-the-repository). - **The sample account is a tutorial** : a new account comes with a sample shop (schemas, custom APIs, hooks, an event, a migration, a utility class) written to be read. Point the assistant at `src/custom_apis/` before asking for something similar. ## AGENTS.md in your repository Agents such as Codex, Cursor, Copilot and Claude Code read a file called `AGENTS.md` at the root of a folder before they work in it. API Maker writes one into the [Git repository](https://docs.apimaker.dev/v4/docs/Git/git.html) of the account on every commit, so an agent knows API Maker before its first question : - **Where things are** : the folder of every kind of item, the files of an item (its YAML, its code, its settings in TypeScript), how to add one, and the files API Maker writes, which an agent never edits. - **How code is written** : `main` and `g` in all eight languages, the calls of `g.sys`, hooks, utility classes, test cases, and where the exact types are (`am-types/types.ts`, `src/types/db-interfaces.d.ts`). - **The rules of security** : the two gates, the row scoping pre-hook, secrets, what code must never do. - **The security report** : how to read `src/api_security_report/report.md`, fix a finding in the file it names and see it go, without ever skipping a finding : a skip is the decision of your team. - **How to check a change** : the local client, `npm run test`, the type checks of each language, and the pages of these docs as Markdown. It is about 13 KB, short enough to be read at the start of every session, and it goes with the version of API Maker : an update of API Maker brings the guide of that version with the next commit. The guide is a block between two lines, `` and ``. Every commit writes the block again; what you write before or after it is yours and stays as it is. A repository which has an `AGENTS.md` of its own gets the block after its text. **AGENTS.md** ```markdown # API Maker project : guide for AI agents … # Our team - Every new table gets a row scoping pre-hook before its first API user. - Ask Diya before a migration script which deletes rows. ``` - The file comes to your folder with `git pull`, with the rest of the commit. The local client does not write it : git refuses a pull which would replace a file it does not track. - The Git page lists it under **AGENTS.md (guide for AI agents)** the first time, and after an update of API Maker which changed the guide. It can not be reverted from the page : the next commit writes it again. - Claude Code reads `CLAUDE.md` : a `CLAUDE.md` with the line `@AGENTS.md` makes it read the guide too. ## Swagger for the APIs of your account Every API user can have its own Swagger (OpenAPI) document with the APIs it may call, with a URL to share : enable it on the [API user](https://docs.apimaker.dev/v4/docs/features/developer-tools.html#swagger-docs-per-api-user). An assistant which generates a client for your APIs reads it directly. > **Tell us what is missing** > > If an assistant gives a wrong answer about API Maker, the page it read is probably unclear. Write to [contact@apimaker.dev](mailto:contact@apimaker.dev) with the question and the page ; it helps every reader.