Build APIs and deploy a database
After creating a schema file (.sfn), turn the design into a working service. API Build prepares create, read, update, and delete APIs for every table and shows who can use each address.
You can also connect custom query APIs, static file APIs, and real-time events to the same service.
Before you begin
- Required permission: A user with database permission
- Prerequisite: Create a schema file (
.sfn) first.
Open API Build
Select the API Build tab at the top of the schema screen to review the automatically generated APIs for each table.

Automatically generated APIs
Five APIs are generated for each table by default. You can also add custom APIs when needed.
| Method | Endpoint | Description |
|---|---|---|
| GET | .../list | Retrieve a list |
| GET | .../view/:id | Retrieve one record |
| POST | .../create | Create a record |
| PUT | .../update/:id | Update a record |
| DELETE | .../delete/:id | Delete a record |
Use Add new API (Custom Endpoint) to define an API with the required query and response shape. Use Add static file API to serve JSON, XML, HTML, image, and binary files from the workspace with the appropriate file type.
Serve a file or folder through an API
- Select
Add static file API. - Under
Storage space, chooseTeam spaceorPersonal space. - Under
Source type, chooseSingle fileorFolder list · file content, then useChoose fileorChoose folderto select the source. - For a folder, set
Allowed extensionsandInclude subfolders. Leaving the extensions empty includes all file types. - Under
Response mode, choose whether to show content in the browser (Display in browser) or return it as a file (Download). - Review the endpoint permissions, then deploy the schema.
A single-file endpoint returns that file. A folder endpoint creates both a JSON file list and an address that reads content by an item's id. Renaming or moving a file changes its path-based id, so clients should use the latest id or viewUrl from the list response.
Feature endpoints control permissions for service-wide capabilities such as real-time sockets, file and image uploads, and AI responses.

Import real-time events and REST settings
Under Event definitions for the real-time socket, you can define events alone or import a JSON or YAML bundle that also contains the required tables and REST settings.
- Select
Paste AI answerand paste the bundle. You can paste a bundle you prepared yourself in the same format. - Choose
Merge by nameto retain existing events, orReplace allto replace the current event definitions. - In
Preview, review the events to add, change, or remove and the counts of tables, columns, and REST endpoints to add. - Review REST conflicts and any items that were normalized or skipped. Select
Overwrite conflicting REST settingsonly when the existing REST settings must change. - Review the server check, fix its errors, and select
Apply.
Importing changes the schema currently being edited. The service changes only after you complete Deploy. The server checks the event and REST rules again during deployment and rejects the deployment if they do not pass.

Building APIs beyond CRUD with a custom endpoint
When the 5 auto-generated APIs (list/view/create/update/delete) aren't enough, clicking Add new API (Custom Endpoint) lets you define behavior in much finer detail.

Operation kind
Beyond the 5 basic CRUD actions, the Operation kind dropdown also offers:
| Operation kind | Meaning |
|---|---|
| Action | For imperative, command-style endpoints that don't fit CRUD |
| Stats | Returns statistical results like counts, sums, or aggregates |
| Bulk | Processes multiple records in one call |
| Export | Downloads query results as a file |
Scope is one of Collection (the whole table or multiple records, usually a path without :id), Item (one specific record), or Command (a custom, command-style endpoint that doesn't fit CRUD).
Permissions use the same 3 tiers as the REST API
Custom endpoints use the same permission options as the auto-generated APIs.

Choosing Member + Additional Conditions lets you combine level, team, admin status, and owner (self) conditions — the same way you'd restrict "level 2 or higher" or "sales team only" on an auto-generated REST endpoint, you can apply it to a custom endpoint too.
Writing raw SQL
On the Processing flow tab, Base query has an editor where you write the SQL this endpoint runs. On an auto-generated API, switching Base query to Hand-written SQL opens the same editor.

The REST API list's Processing column also shows an SQL badge marking that this endpoint runs a query you wrote directly. Conditions the auto-generated APIs can't express — like "reject if this member has already created 3 or more rows today" — can only be built with this SQL editor.
Check SQL and parameters
As you type SQL, the browser checks its syntax and the tables and columns in the current schema. If an error or warning includes a line and column, select it to move to that position in the editor. You can also open SQL with errors from the deployment area.
This check does not run the query against your database. After deployment, call the API to verify database-specific functions, access permissions, and results with real data.
The parameter list shows the :name values used in the SQL. The server fills the reserved values :id, :user_id, :nick, and :now. Other values come from the query string for read requests or the request body after input processing for write requests. Missing values become NULL.
Changing request handling with the processing flow
Without writing SQL, you can also add pre-built functions on the Processing flow tab in sequence to change how a request is processed. Functions fall into three stages: Input, Database, and Output.

| Category | Function | Description |
|---|---|---|
| Input | Validate input | Validates required fields/format, returns 400 on failure |
| Input | Session value | Auto-fills a field with a session value (e.g. user_id) |
| Input | Default value | Fills empty fields with a default value |
| Input | Move key | Moves a request body key to a table column name |
| Database | Condition | Adds a WHERE condition |
| Database | Page size | Handles limit/offset automatically |
| Database | Sort | Sets the ORDER BY clause |
| Output | Hide fields | Removes a column from the response |
| Output | Rename key | Renames a key in the response JSON |
| Output | Add aggregate | Adds an aggregate value like COUNT/SUM to the response |
| Output | Webhook | Sends the event to an external URL |
Configure permissions
Configure access separately for each API. A member here is an existing workspace member account. You do not need to create another sign-in or authentication system because workspace members, levels, and teams are connected directly to API permissions.
| Permission | Description |
|---|---|
| Members only | Any signed-in member can call the API |
| Member + Additional Conditions | The member must also satisfy conditions such as level, team, or administrator status |
| Anyone | Can be called without signing in, but create, update, and delete requests are not allowed |
Deploy
Enter the deployment information as follows.
Database identifier: Enter the logical DB name to use on the deployment server in English.Storage engine mode: Select SQLite3, PostgreSQL, MySQL, or MariaDB. For an external DB, also enter the host, port, DB name, user, and password. MySQL and MariaDB use an InnoDB-based configuration.- Under
GeneralandAdvanced, review the following items.
| Item | Description |
|---|---|
Client deployment path | Found under General. Select where the sample frontend output (index.html, test.html, README, and other files) will be created |
IP restriction | Found under Advanced. Specify an allowlist of IP addresses that may access the APIs |
Select Deploy in the deployment section below the API list to open its settings. This section stays fixed at the bottom of the editor, so it remains visible while you scroll the API list. The first selection does not deploy anything. Review the settings, then select Deploy again to prepare the database and APIs. If you selected a client deployment path, Webspace also creates a sample interface for testing the APIs. Continue with Review the frontend sample to modify the interface.
API request examples
The following examples use the user_profile table.
GET /api/web/{dbName}/user_profile/list
GET /api/web/{dbName}/user_profile/view/{id}
POST /api/web/{dbName}/user_profile/create
PUT /api/web/{dbName}/user_profile/update/{id}
DELETE /api/web/{dbName}/user_profile/delete/{id}
Create (POST) request example:
POST /api/web/{dbName}/user_profile/create
Content-Type: application/json
{
"email": "user@example.com",
"is_active": true
}
Read error responses
When a request fails, check its HTTP status and code or errorCode. Codes stay the same across languages: use them to decide whether to request sign-in or retry, and use message for display.
Built-in WebSpace error messages support Korean, English, Japanese, Simplified Chinese, and German. The signed-in account's language takes precedence. If it is absent or unsupported, the server consults the request's Accept-Language header. English is the fallback when neither matches. Do not compare display text in an API integration.
For example, a request requiring sign-in returns these fields:
{
"code": "WEBSPACE_LOGIN_REQUIRED",
"errorCode": "WEBSPACE_LOGIN_REQUIRED",
"message": "Sign in to continue."
}
These are the key fields to inspect, not a complete response example. REST, static-file, and administration APIs may use different envelopes.
- Input validation keeps the existing
ok: falseanderrorslist. Checkokeven when HTTP status is 200, and use each item'sfield,code, andmessageto explain the issue. - WebSocket failures appear in
datawithin atype: "error"message. The existing routingkeyis preserved;codeanderrorCodeidentify the cause. - Physical server paths, SQL, and raw internal errors are not returned to users. When operator investigation is needed, provide the time, request path, HTTP status, and error code.
Deployment and overwriting
Overwriting a schema whose database already contains data follows the server deployment policy. Your organization can prohibit it or restrict it to administrators and designated deployment operators. Before changing the structure, review affected columns and APIs and confirm backup and recovery procedures.
Good to Know
- APIs use SetFN sign-in sessions for authentication. Unauthenticated requests are rejected unless the API permission is set to
Anyone. - Changing the schema structure also updates its API endpoints. Check compatibility with existing integrations.
- SQLite3 data is stored in the server's WebSpace storage. External-engine data is stored in the database configured by the administrator.
- Use list filters, sorting, and page sizes only within the query ranges allowed by the server.
- For calls from an external site, also check the administrator's allowed origins and CSP settings.