Skip to main content

Definition Structure

A Custom API definition is a single YAML file with six top-level sections.

identifiers:    # who owns this definition
permission: # who can call this endpoint
http: # URL, method, version
logic: # ordered execution steps
config: # runtime behaviour
database: # connection config

identifiers

Ties the definition to its organizational context. All five fields are required.

identifiers:
org_id: 01KC11784DW133S3THR7JTQNQ1
project_id: 01KC11KZ6VDMMKJZ4YWQYKYZ6Z
feature_id: 01KBY3K8RQ9GS1VD9XYXHZ92QT
space_id: 01KBY3K97GMAJFBQ0PP7158NZH
user_id: 01KBY3K9NDC5XW523M2V1Z0373
FieldDescription
org_idOrganization owning this definition
project_idProject within the organization
feature_idUnique identifier for this definition — generate a new ULID for each
space_idUnique identifier for this Workspace — user workspace, dev, staging, or prod
user_idUser creating or last modifying this definition

All IDs use ULID format. See ID Format.


permission

Roles allowed to call this endpoint. Uses OR logic — the user needs any one matching role.

permission:
[ power, admin ]

At runtime, Minimal reads X-User-Roles from the request header and checks for a match:

X-User-Roles: editor,admin
permission: [ power, admin ]

→ admin ∈ [ power, admin ] ✅ Allowed

If no role matches, Minimal returns 403 Forbidden.

note

Definition management endpoints (create, update, delete) always require power or admin regardless of what is set here.


http

Defines the endpoint URL, method, and input format.

http:
uri: users/all
method: get
version: 0.1
input_type: json
FieldValuesDescription
uriStringFinal path segment only — no leading slash, no org or project prefix
methodget post put patch deleteHTTP method
versionSemver stringUsed for rollback — increment on each update
input_typejsonExpected request body format

The registered endpoint URL is:

{method} {yourdomain}/{org_abbreviation}/{project_abbreviation}/{uri}

For example, with org abbreviation lbl, project abbreviation crm, and uri: users/all:

GET https://your-domain.com/lbl/crm/users/all

logic

An ordered list of execution steps. See Logic Steps for full details.

logic:
- sql: |
SELECT * FROM users
omit: true

- lark: transform
omit: false
code: |
result = [{"id": row["id"]} for row in step_0]

Three step types are available — sql, lark, and expr.


config

Controls runtime behaviour for this endpoint.

config:
coalesce: false
rollback_version: 0.1
cache_result: true
FieldDefaultDescription
rollback_versionVersion to revert to if this definition fails
cache_resultfalseCache the response for repeated identical requests

database

Connection config for the database this endpoint queries.

database:
type: mysql
source_ip: localhost
port: "3306"
username: john
password: 'pas****'
name: my_database
timeout_secs: 30
idle_timeout_secs: 600
max_open_connections: 50
max_idle_connections: 25
FieldDescription
typeclickhouse, postgres, or mysql
source_ipDatabase host
portPort as a string
usernameDatabase user
passwordEncrypted password — never plaintext
nameDatabase name
timeout_secsQuery timeout in seconds
idle_timeout_secsHow long idle connections are kept alive
max_open_connectionsMaximum connections in the pool
max_idle_connectionsIdle connections to retain in the pool
Never store plaintext passwords

Passwords in database.password must be encrypted. Treat them the same as database credentials — never commit plaintext values.