API Tokens and OpenAPI
Every API used by Gately's management UI can be called over HTTP. Scripts and automation authenticate with API tokens, and the API reference is generated automatically from the registered routes.
API tokens
UI path: sidebar "System" group → "API Tokens".
Create a token
Click "New Token" and fill in:
| Item | Description |
|---|---|
| Name | Required, up to 64 characters, identifies the purpose, such as "monitoring script" |
| Expiry | Choose "Never expires", 7 days, 30 days, 90 days, 1 year or a custom date; a custom time must be later than now |
| Permissions | Required, select at least one. A new token has no permissions by default |
Each instance can store up to 100 tokens.
After creation, the dialog shows the plaintext token only once, in the format gtl_ followed by 48 hexadecimal characters. Only the SHA-256 hash is stored on disk. If you lose it, you can only "Regenerate" it, and the old value stops working immediately. The list identifies tokens with a hint in the form gtl_xxxx…yyyy, and shows the last used time and source IP (persisted to disk with a delay of up to one minute).
Editing a token lets you change its name, permissions, expiry and enable switch. Changes take effect immediately and the plaintext token stays the same. An expired token can keep its original expiry while you change only the other fields.
Authentication
Send Authorization: Bearer <token> in the request header:
curl -H "Authorization: Bearer gtl_xxxx" http://localhost:16680/api/statusRequest bodies use Content-Type: application/json, and errors are returned uniformly as {"error": "message"}. If a token is disabled, expired or unknown, the request is still checked as a login session and ends up with a not-logged-in error.
Scopes
A permission has the form <scope>:read or <scope>:write, and write includes read. A scope is a module ID (such as ddns, portforward, notify, backup) or one of three built-in scopes:
| Scope | Name | Available permissions | Endpoints |
|---|---|---|---|
status | System status | status:read | /api/status, /api/system/info, /api/system/update |
logs | System logs | logs:read | /api/logs |
import | Lucky config import | import:write | /api/import/lucky |
Wildcards:
| Form | Meaning |
|---|---|
*:read | Read-only access to all modules |
*:write or * | Read/write access to all modules |
ddns:read | Read-only access to DDNS only |
The permission an endpoint needs is determined by its path and method:
- A path
/api/<module>/...needs a permission for the<module>scope: GET and HEAD requireread, and other methods requirewrite. - Module logs
GET /api/<module>/logsare read-only, and clearing logs (DELETE) is a write operation. - The following GET endpoints return sensitive content or open an interactive channel, so they are treated as
write: endpoints whose path contains aws(WebSocket terminal),exec,download,export,read,configorpreview-archivesegment, for example certificate download, running commands in a container and reading files. GET /api/sessionandGET /api/openapi.jsonaccept any valid token.
Operations tokens cannot perform
The following endpoints accept login sessions only, and any token access returns 403:
- Account and two-factor authentication:
/api/account - Token management:
/api/tokens - System settings, system token, restart, online upgrade:
/api/system/settings,/api/system/token,/api/system/restart,/api/system/upgrade - Configuration backup download and restore:
/api/system/backup,/api/system/restore - Local backup file download:
/api/backup/local - Web Terminal security settings:
/api/webterminal/security - Login and logout:
/api/login,/api/logout
A request with insufficient permissions returns token lacks permission <permission> and records a warning in the system logs, including the token name, source IP and the rejected endpoint.
Legacy token
The single global token from older versions is migrated automatically on upgrade into a token named "Legacy token (migrated from an older version)" with the permission *, marked "Legacy" in the list. Create new tokens with only the permissions they need and delete it. "Regenerate" on the legacy token also removes the legacy mark.
Recommendation
Create a separate token for each script, select only the permissions it needs, and set an expiry. If a token leaks, delete or regenerate just that one.
OpenAPI and API docs
The docs page in the management UI
Sidebar "System" group → "API Docs". The page shows the Base URL and authentication notes, lists all endpoints grouped by feature, and supports searching by path or summary. Expanding an endpoint shows the required permission, parameters, request body fields and a copyable curl example. Endpoints that need a login session are marked "Login session only" and have no curl example.
Get the OpenAPI document
While an instance is running, GET /api/openapi.json returns an OpenAPI 3.0 document that any valid token or login session can read:
curl -H "Authorization: Bearer gtl_xxxx" http://localhost:16680/api/openapi.json -o openapi.jsonThe document uses the bearerAuth security scheme and adds extension fields to each endpoint:
| Extension field | Meaning |
|---|---|
x-required-scope | The token permission needed to access this endpoint |
x-token-allowed | Whether tokens may access it; false means login session only |
x-scope-domains (document root) | List of all scopes |
The endpoint list used by CLI and MCP is read from this document.
Command-line export
The -api-docs flag builds the application in a temporary configuration directory (it listens on no port and does not affect your existing configuration), writes the documents to the specified directory and exits:
gately -api-docs ./api-docsIt outputs two files:
openapi.json: the OpenAPI 3.0 descriptionAPI.md: the Markdown API docs, with a quick start, a scope table and endpoint tables grouped by feature
Examples
# View system status (requires status:read)
curl -H "Authorization: Bearer gtl_xxxx" http://localhost:16680/api/status
# List all DDNS tasks (requires ddns:read)
curl -H "Authorization: Bearer gtl_xxxx" http://localhost:16680/api/ddns/tasks
# Sync a DDNS task immediately (requires ddns:write; take the key from the list returned by the previous step)
curl -X POST -H "Authorization: Bearer gtl_xxxx" http://localhost:16680/api/ddns/tasks/KEY/sync
# Fetch only module logs with a sequence number greater than 10 (requires ddns:read)
curl -H "Authorization: Bearer gtl_xxxx" "http://localhost:16680/api/ddns/logs?since=10"
# Fetch only the newest 200 entries, then pass the smallest seq as before to page back
curl -H "Authorization: Bearer gtl_xxxx" "http://localhost:16680/api/ddns/logs?limit=200"
curl -H "Authorization: Bearer gtl_xxxx" "http://localhost:16680/api/ddns/logs?before=1200&limit=200"Full API reference
See the API Reference for all endpoints, parameters and required permissions.