# Form.io Concepts

## Forms

A **Form** is the primary way data enters the platform. Forms are built using the drag-and-drop Form Builder to arrange **components**, which can be thought of as the fields that make up a for&#x6D;**.**

Forms may be created in three display modes:

* **Web Form** - a standard single-page form.
* **Wizard** - displays a web form in a multi-step format with navigation between pages.
* **PDF** - a fillable PDF that overlays Form.io components on a document.

As a form is built Form.io simultaneously constructs the JSON schema and defines a REST API endpoint. This allows the form to be fully portable, embeddable, and programmatically accessible.

Forms collect "ad hoc" data, generally through a form user's input.

***

## Resources

A **Resource** is a structured data object within a project. Resources are built using the same drag-and-drop Form Builder to arrange components. Resources are used to define reusable data models that other forms and resources can reference.

Think of a Resource as a database collection with a built-in schema. Common examples include:

* A **User** resource that stores name, email, and a role for application users.
* A **Customer** resource that might be used across multiple forms such as orders, returns, and support.&#x20;
* A **Product** resource that populates the selections available on an Order form.

Once a Resource is populated with submission data, it functions like a RESTful database. Entities can be created, read, updated, deleted, and queried through the same automatically generated API. Other forms can reference Resource data using components like the **Select Resource** field, enabling complex relational data structures.

Forms vs. Resources — when to use which:

<table><thead><tr><th width="202.62890625"></th><th>Forms</th><th>Resources</th></tr></thead><tbody><tr><td><strong>Function</strong></td><td>Collect unstructured / supplemental data</td><td>Define structured, reusable data objects</td></tr><tr><td><strong>Examples</strong></td><td>Job application, feedback survey</td><td>Employee profile, Cost Center list</td></tr><tr><td><strong>Referenced by others?</strong></td><td>Rarely</td><td>Frequently, resources populate form fields</td></tr><tr><td><strong>Typical use</strong></td><td>One-time or event-driven submissions</td><td>Persistent records queried by the application</td></tr></tbody></table>

***

## Components

**Components** are the building blocks of every form and resource. Components are dragged from the palettes of available components onto the Form Builder canvas. Components capture input through a variety of fields. Each component is stored as a JSON object within the form's schema, and defines how the input is stored in submission data.

Every component can be configured in a variety of ways to customize the appearance and functionality, altering the way the field appears, the way data is validated, and more.

Developers who need functionality beyond the built-in library can create **custom components** by extending an existing component class and registering it with the renderer.

***

## Projects

A **Project** is the top-level organizational unit in Form.io. Typically, a single project corresponds to a single application. All collateral developed in Form.io (forms, resources, roles, submission data) are contained within a project. Projects shares a single domain API endpoint.

Projects serve as a scope boundary for Form.io users. A particular form builder might be granted permission to create forms in one project but not another, while a form user may view submissions in one project but not others. Every element within a project is encapsulated within that project's context; roles, data, and permissions in one project are distinct to that project, and cannot be shared or accessed from a different project.

A project can contain an unlimited number of forms, resources, and developers, and can handle an unlimited number of API submission calls.

***

## Developer Portal

The **Developer Portal** is the web-based UI where platform users manage everything: projects, forms, resources, roles, submissions, stages, teams, and integrations. It is the primary interface for form builders and developers during the build phase.

Form users (the people who fill out forms in production) do **not** interact with the Developer Portal. They access forms through the application that embeds and renders them using the Form.io JavaScript renderer.

***

## Form JSON

Every form and resource in Form.io is represented under the hood as Form JSON. Form JSON is a  JSON object that describes the form's title, display type, API path, and the full tree of components with their settings, validation rules, conditional logic, and layout.

A simplified example:

```json
{
  "title": "Person",
  "display": "form",
  "type": "form",
  "name": "person",
  "path": "person",
  "components": [
    {
      "type": "textfield",
      "key": "firstName",
      "label": "First Name",
      "input": true
    },
    {
      "type": "email",
      "key": "email",
      "label": "Email",
      "input": true
    },
    {
      "type": "button",
      "key": "submit",
      "label": "Submit",
      "action": "submit",
      "input": true
    }
  ]
}
```

The JSON schema is the single source of truth for a form. It powers three critical functions:

1. **Rendering -** The JavaScript form renderer reads the JSON and displays the form in the browser. No server-side rendering is needed as the form is fully described by its schema.
2. **API generation -** The server uses the same JSON to generate the REST API endpoints and validate incoming submission data.
3. **Portability -** Because the form is just JSON, it can be versioned, exported, imported, migrated between stages, and stored in source control.

The Form Builder UI updates the JSON schema in real time as components are arranged and configured.

***

## Submissions

A **Submission** is a single data record created when a user fills out and submits a form or resource. The submission payload is a JSON object whose structure mirrors the `key` values defined in the form's components.

In the "Person" form example above, a submission would look like:

```json
{
  "data": {
    "firstName": "Jane",
    "email": "jane@example.com"
  }
}
```

Submissions are the data layer of the platform. Submissions are:

* **API-accessible** - Every submission is reachable via the REST API at a URL of the form `{projectUrl}/{formPath}/submission/{submissionId}`.\
  Submissions can be created, read, updated, deleted, filtered, and paginated through the API.
* **Owned** - Each submission has an owner (the user who created it), which is used by the permissions system to enforce \_own vs. \_all access control.
* **Portable** - In addition to API access, submission data can be viewed in JSON, CSV, or PDF formats directly from the Developer Portal.
* **Revision-tracked** - Submission Revisions (available with the Security & Compliance package) provide an audit log of who changed a submission, when, and what was modified, with the ability to revert to previous versions.
* **Collection-configurable** - Submissions can optionally be directed to separate database collections on a per-form basis for compliance or performance requirements.

***

## Actions

**Actions** are configurable server-side operations that execute when a form is submitted. Every form can have an unlimited number of actions that execute sequentially. Actions can be used as a bridge to other parts of an application or integrated systems.

Actions are where integration and workflow logic lives. The built-in actions include:

* **Save Submission -** Saves the submission data. By default every form has this action, saving data to itself. It can also be configured to route data to a different Resource (e.g., a Registration form that saves to a User resource).
* **Email -** Sends an email using a configured email transport (SMTP, SendGrid, Mailgun, or Mandrill) with customizable templates that can include submission data.
* **Login -** Authenticates a user by generating a JWT token based on the submitted credentials.
* **Webhook -** Sends the submission payload to an external API endpoint in real time, enabling integration with any external system.
* **Integrations -** Sends submission data to third-party providers.

***

## Roles & Permissions

Form.io uses a **role-based access control (RBAC)** system to govern who can do what within a project. The system is built on two concepts: **Roles** (which are assigned to users) and **Permissions** (which are given to roles).

### Roles

Every new project starts with four default roles:

* **Anonymous** - Reserved for unauthenticated users (e.g., someone filling out a public survey or a login form). Cannot be deleted.
* **Everyone** - A role that represents any user assigned to any role, including anonymous ones. When a permission is given to **Everyone**, every role in the project inherits that permission. Cannot be deleted.
* **Authenticated** - A starting role for logged-in users.
* **Administrator** - A starting role for users with elevated privileges.

Additional custom roles can be added. Each role has a unique ID scoped to its project. Roles exist within the Project context and cannot cross project boundaries.

### Permissions

Permissions are organized across three scopes:

<table><thead><tr><th width="282.39453125">Scope</th><th>What it controls</th></tr></thead><tbody><tr><td><strong>Project</strong></td><td>Who can create, read, update, or delete project-level elements (forms, roles, settings).</td></tr><tr><td><strong>Form Definition</strong></td><td>Who can read, update, or delete a specific form's JSON schema.</td></tr><tr><td><strong>Submission Data</strong></td><td>Who can create, read, update, or delete the data submitted through a specific form.</td></tr></tbody></table>

Within each scope, eight permission types are available:

| Own         | All        |
| ----------- | ---------- |
| Create  Own | Create All |
| Read Own    | Read All   |
| Update Own  | Update All |
| Delete Own  | Delete All |

"Own" permissions restrict users to records they own (typically records they created). "All" permissions grant access to all records, regardless of ownership.  \
As a general rule, "All" permissions are for administrative roles and "own" permissions are for end users.

{% hint style="info" %}
By default, forms allow all roles to *read* the form definition (so the form can be rendered in the application), but submission access is disabled for every form. You must explicitly grant submission permissions for users to interact with a form's data.
{% endhint %}

***

## Teams

**Teams** enable collaboration by granting groups of developers and form builders access to projects and stages. A team is created at the portal level (outside any individual project). Teams can then be assigned to one or more projects.

Teams can operate at two levels:

* **Project-level** - Grants the team access to the entire project.
* **Stage-level** - Grants the team access to a specific stage of a specific project (e.g., the Development stage) without access to other stages like Live.

Stage-level teams support two permission tiers: **Stage Read** (view forms and data, but cannot modify) and **Stage Write** (view and modify forms and data).

***

## Stages

**Stages** deliver control over a project's development lifecycle, such as authoring, testing, and production. By default, every project has a **Live** stage that represents the production environment.

Additional stages can be created to match a team's SDLC. A typical configuration includes:

| Stage           | Purpose                                                                                           |
| --------------- | ------------------------------------------------------------------------------------------------- |
| **Live**        | The production stage connected to the production environment.                                     |
| **Authoring**   | Where form builders create and modify forms before they are ready for testing.                    |
| **QA / Test**   | Where stage versions are deployed and tested in a live-like environment before promotion to Live. |
| **Development** | A dedicated stage for developers to test new platform releases or application changes.            |

Each stage can be connected to its own **Environment** (a separate backend with its own database and Form.io server containers), or multiple stages can share an environment. **Stage Versions** allow you to snapshot a project's forms, resources, actions, and roles and deploy that version from one stage to another, enabling controlled promotion workflows.

Stages can also be placed in **Protected Mode**, which prevents modifications to forms, resources, roles, and project access, often used for any stage connected to a live application.

***

## The API Layer

One of Form.io's defining characteristics is that every form and resource automatically generates a full REST API. There is no separate step to define or deploy an API. The API is created alongside the form and is functional the moment the form is saved.

### API URL Structure

The API is hierarchical, mirroring the project > form >submission structure:

<table><thead><tr><th width="170.45703125">Scope</th><th>URL Pattern</th><th width="336.41015625">Example</th></tr></thead><tbody><tr><td><strong>Project</strong></td><td><code>{baseUrl}/{projectName}</code></td><td><code>https://myenv.com/hrapp</code></td></tr><tr><td><strong>Form / Resource</strong></td><td><code>{projectUrl}/{formPath}</code></td><td><code>https://myenv.com/hrapp/employee</code></td></tr><tr><td><strong>Submission</strong></td><td><code>{formUrl}/submission/{id}</code></td><td><code>https://myenv.com/hrapp/employee/submission/abc123</code></td></tr><tr><td><strong>Action</strong></td><td><code>{formUrl}/action/{id}</code></td><td><code>https://myenv.com/hrapp/employee/action/def456</code></td></tr><tr><td><strong>Role</strong></td><td><code>{projectUrl}/role/{id}</code></td><td><code>https://myenv.com/hrapp/role/ghi789</code></td></tr></tbody></table>

Standard HTTP methods apply: `GET` to read, `POST` to create, `PUT` to update, `DELETE` to remove. Submissions support filtering, pagination, and sorting through query parameters.

### Authentication

API requests are authenticated using **JSON Web Tokens (JWT)**. When a user logs in through a Form.io Authentication (usingLogin action) or an OAuth/SAML/LDAP flow, the platform issues a JWT that is included in subsequent API requests as an `x-jwt-token` header. The server evaluates the token to determine the user's roles and enforces the permission rules described above.

### JavaScript SDK

The platform provides a JavaScript SDK (`Formio` class) that wraps the API and provides convenient methods for common operations. The SDK mirrors the hierarchical URL structure:

```js
// Project scope
const project = new Formio('https://myenv.com/hrapp');

// Form scope
const form = new Formio('https://myenv.com/hrapp/employee');

// Submission scope
const submission = new Formio('https://myenv.com/hrapp/employee/submission/abc123');
```

The SDK is used internally by the Form.io renderer and is also available for direct use in application code.

### API Explorer

The Developer Portal includes a built-in **API Explorer** (powered by Swagger) that visualizes all the API endpoints generated by the forms and resources in your project. It is a live explorer — requests made through it execute against the real API.

***

## Multi-Tenancy

For SaaS and multi-tenant applications, Form.io supports **Multi-Tenancy.** This offers the ability to create isolated tenant sub-projects within a single parent project. Each tenant functions as a self-contained project with its own API endpoint, forms, resources, data, authentication, file storage, and access permissions, while inheriting CORS settings from the parent project.

This architecture allows a single deployment to serve multiple customers or organizational units, each with full project-level isolation, managed from a unified Developer Portal interface.

***

## Customer Applications

Through most Form.io documentation **Application** refers to the Application that developers are building outside of **Form.io**, and which will embed the Form.io Rendered.

**Form.io** major components are created within the **Form.io** system, but are ultimately used in the customer Application. It is important to distinguish a customer Application from the work being completed within **Form.io**.

***

## How It All Fits Together

The diagram below summarizes the relationships between these concepts:

```
Project
├── Forms ──────────── (built via Form Builder, stored as JSON Schema)
│   ├── Components     (drag-and-drop fields that define data structure)
│   ├── Actions        (server-side operations: save, email, webhook, login…)
│   ├── Submissions    (data records created by form users, accessible via API)
│   └── Access         (per-form permission assignments using Roles)
│
├── Resources ──────── (structured data objects, same builder as Forms)
│   ├── Components
│   ├── Actions
│   ├── Submissions
│   └── Access
│
├── Roles ─────────── (Anonymous, Authenticated, Administrator, custom…)
├── Stages ────────── (Live, Authoring, QA, Development…)
├── Teams ─────────── (groups of users with project/stage access)
└── API ───────────── (auto-generated REST endpoints for every form & resource)
```
