---
# System prepended metadata

title: Form Builder API Reference

---

# Form Builder API Reference

## SignalR Hub (Websocket)

The Form builder SignalR Hub URL is

```txt
{backend-url}/FormBuilderHub
```

Events (`Message Names for subscription`):

- Session Events
  - `AllSessionsFormBuilderClosedEvent`
  - `UserJoinedFormBuilderEvent`
  - `UserLeftFormBuilderEvent`
- Form Events
  - `ControlAddedEvent`
  - `ControlMovedEvent`
  - `ControlRemovedEvent`
  - `FormHistoryRevertedEvent`
  - `PropertyValueChangedEvent`

Requests (`Methods to be invoked`):

- Session Requests
  - `JoinFormBuilder`
  - `Authorize`
- Form Requests
  - `AddControl`
  - `ChangePropertyValue`
  - `MoveControl`
  - `RemoveControl`
  - `RevertFormHistory`

### Authorize User

This method should be called after connecting with the signalR Hub, It should also be called if the current token has been expired to send a new valid token.

> Note: This method is a mock and accepts any string and create a random userid for the session.

```cs
Result<bool> Authorize(string accessToken);
```

Response:

```json
{
  "hasErrors": false,
  "data": false,
  "errors": [
    {
      "code": "...",
      "description": "..."
    }
  ]
}
```

Errors:
| Code                       | #   | Notes         |
| -------------------------- | --- | ------------- |
| `InternalServerError`      |     | Unknown Error |

### Join for Specific Form

This method should be called once the user is authorized before getting any data or sending any form related requests.

```cs
Result<bool> JoinFormBuilder(Guid formId)
```

Response:

```json
{
  "hasErrors": false,
  "data": false,
  "errors": [
    {
      "code": "...",
      "description": "..."
    }
  ]
}
```

Event Published to the others:
`UserJoinedFormBuilderEvent`

```json
{
  "id": "Guid",
  "formId": "Guid",
  "userId": "Guid",
  "dateOccurred": "2021-11-22T17:48:48.626Z"
}
```

Errors:
| Code                       | #   | Notes                    |
| -------------------------- | --- | ------------------------ |
| `Hub:UnAuthorized`         |     |                          |
| `Hub:ChangeFormNotAllowed` |     | User resend join request |
| `InternalServerError`      |     | Unknown Error            |

### Add Control

```cs
Result<AddControlResponse> AddControl(AddControlHubRequest request);
```

Request:

```json
{
  "controlId": "Guid",
  "controlType": "Page",
  "parentId": "Guid or null",
  "order": "1"
}
```

Response:

```json
{
  "hasErrors": false,
  "data": {
    "control": { } // one of `BasicControl` driven types
  },
  "errors": [
    {
      "code": "...",
      "description": "..."
    }
  ]
}
```

Event Published to the others:
`ControlAddedEvent`

```json
{
  "id": "Guid",
  "formId": "Guid",
  "userId": "Guid",
  "dateOccurred": "2021-11-22T17:48:48.626Z",
  "control": { } // one of `BasicControl` driven types
}
```

Errors:
| Code                       | #   | Notes                       |
| -------------------------- | --- | --------------------------- |
| `Hub:UnAuthorized`         |     |                             |
| `Hub:UnKnownSessionForm`   |     | User didn't join a form     |
| `InternalServerError`      |     | Unknown Error               |
| `InputValidationError`     | (1) | formId is default Guid ⚠️   |
| `InputValidationError`     | (2) | controlId is default Guid   |
| `InputValidationError`     | (3) | Page with not null parentId |
| `InputValidationError`     | (4) | Not Page with null parentId |
| `Form:FormNotFound`        |     | ⚠️                          |
| `Form:ParentNotFound`      |     |                             |
| `Form:InvalidControlId`    |     |                             |
| `Form:InvalidControlOrder` |     |                             |

### Move Control

```cs
Result<MoveControlResponse> MoveControl(MoveControlHubRequest request);
```

Request:

```json
{
  "controlId": "Guid",
  "parentId": "Guid or null", // NewParent
  "order": "1"
}
```

Response:

```json
{
  "hasErrors": false,
  "data": {
    "controlId": "Guid",
    "parentId": "Guid or null",
    "order": "1"
  },
  "errors": [
    {
      "code": "...",
      "description": "..."
    }
  ]
}
```

Event Published to the others:
`ControlMovedEvent`

```json
{
  "id": "Guid",
  "formId": "Guid",
  "userId": "Guid",
  "dateOccurred": "2021-11-22T17:48:48.626Z",
  
  "controlId": "Guid",
  "parentId": "Guid or null",
  "order": "1"
}
```

Errors:
| Code                       | #   | Notes                       |
| -------------------------- | --- | --------------------------- |
| `Hub:UnAuthorized`         |     |                             |
| `Hub:UnKnownSessionForm`   |     | User didn't join a form     |
| `InternalServerError`      |     | Unknown Error               |
| `InputValidationError`     | (1) | formId is default Guid ⚠️   |
| `InputValidationError`     | (2) | controlId is default Guid   |
| `InputValidationError`     | (3) | Page with not null parentId |
| `InputValidationError`     | (4) | Not Page with null parentId |
| `Form:FormNotFound`        |     | ⚠️                          |
| `Form:ControlNotFound`     |     |                             |
| `Form:ParentNotFound`      |     |                             |
| `Form:InvalidControlOrder` |     |                             |

### Remove Control

```cs
Result<RemoveControlResponse> RemoveControl(RemoveControlHubRequest request);
```

Request:

```json
{
  "controlId": "Guid",
  "controlType": "Page"
}
```

Response:

```json
{
  "hasErrors": false,
  "data": {
    "controlId": "Guid",
    "controlType": "Page",
    "deletedIds": [
      "Guid"
    ]
  },
  "errors": [
    {
      "code": "...",
      "description": "..."
    }
  ]
}
```

Event Published to the others:
`ControlRemovedEvent`

```json
{
  "id": "Guid",
  "formId": "Guid",
  "userId": "Guid",
  "dateOccurred": "2021-11-22T17:48:48.626Z",

  "controlId": "Guid",
  "controlType": "Page",
  "deletedIds": [
    "Guid"
  ]
}
```

Errors:
| Code                       | #   | Notes                       |
| -------------------------- | --- | --------------------------- |
| `Hub:UnAuthorized`         |     |                             |
| `Hub:UnKnownSessionForm`   |     | User didn't join a form     |
| `InternalServerError`      |     | Unknown Error               |
| `InputValidationError`     | (1) | formId is default Guid ⚠️   |
| `InputValidationError`     | (2) | controlId is default Guid   |
| `InputValidationError`     | (3) | Page with not null parentId |
| `InputValidationError`     | (4) | Not Page with null parentId |
| `Form:FormNotFound`        |     | ⚠️                          |
| `Form:ControlNotFound`     |     |                             |

### Change Property Value

```cs
Result<ChangePropertyValueResponse> ChangePropertyValue(ChangePropertyValueHubRequest request);
```

Request:

```json
{
  "controlId": "Guid",
  "entityType": "Control", // Form, Control
  "property": {
    "path": ".style.color",
    "value": "\"red\"", // the value should be a valid serialzied json string
  }
}
```

Response:

```json
{
  "hasErrors": false,
  "data": {
    "controlId": "Guid",
    "property": {
      "path": ".style.color",
      "value": "\"red\"", // the value should be a valid serialzied json string
    }
  },
  "errors": [
    {
      "code": "...",
      "description": "..."
    }
  ]
}
```

Event Published to the others:
`PropertyValueChangedEvent`

```json
{
  "id": "Guid",
  "formId": "Guid",
  "userId": "Guid",
  "dateOccurred": "2021-11-22T17:48:48.626Z",
  
  "controlId": "Guid",
  "property": {
    "path": ".style.color",
    "value": "\"red\"", // the value should be a valid serialzied json string
  }
}
```

Errors:
| Code                       | #   | Notes                       |
| -------------------------- | --- | --------------------------- |
| `Hub:UnAuthorized`         |     |                             |
| `Hub:UnKnownSessionForm`   |     | User didn't join a form     |
| `InternalServerError`      |     | Unknown Error               |
| `InputValidationError`     | (1) | formId is default Guid ⚠️   |
| `InputValidationError`     | (2) | controlId is default Guid   |
| `InputValidationError`     | (3) | Page with not null parentId |
| `InputValidationError`     | (4) | Not Page with null parentId |
| `Form:FormNotFound`        |     | ⚠️                          |
| `Form:ControlNotFound`     |     |                             |
| `Form:InvalidProprtyPath`  |     |                             |

### Revert History

> TODO: Not Implemented yet

## Rest APIs (HTTP)

### Create New Form

```txt
POST {backend-url}/api/Forms/Create
{
  "name": "..."
}
```

Response:

```json
{
  "isDeleted": true,
  "createdAt": "2021-12-01T01:10:06.055Z",
  "createdBy": "string",
  "updatedAt": "2021-12-01T01:10:06.055Z",
  "updatedBy": "string",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "name": "string",
  "lastPublishedVersionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "draftedSchema": {
    "isDeleted": true,
    "createdAt": "2021-12-01T01:10:06.055Z",
    "createdBy": "string",
    "updatedAt": "2021-12-01T01:10:06.055Z",
    "updatedBy": "string",
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "lastAppliedEventId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "schema": {},
    "status": 0,
    "concurrencyStamp": "string"
  },
  "draftEvents": [
    {
      "isDeleted": true,
      "createdAt": "2021-12-01T01:10:06.055Z",
      "createdBy": "string",
      "updatedAt": "2021-12-01T01:10:06.055Z",
      "updatedBy": "string",
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "eventData": {}
    }
  ],
  "schemaVersions": [
    {
      "isDeleted": true,
      "createdAt": "2021-12-01T01:10:06.055Z",
      "createdBy": "string",
      "updatedAt": "2021-12-01T01:10:06.055Z",
      "updatedBy": "string",
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "schema": {}
    }
  ]
}
```

### List All Forms

```txt
GET {backend-url}/api/Forms/GetAll
```

Response:

```json
[
  {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "name": "string",
    "lastPublishedVersionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "createdAt": "2021-11-22T17:50:31.036Z",
    "createdBy": "string",
    "updatedAt": "2021-11-22T17:50:31.036Z",
    "updatedBy": "string"
  }
]
```

### Get Form Json Schema

```txt
GET {backend-url}/api/Forms/GetSchema/{formId: GUID}
```

Response:

```json
{
  "schema": {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "templateId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "lastAppliedEventId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "themeId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "status": 0,
    "settings": {
      "format": 0,
      "enableScoreCalculation": true,
      "expirationDate": "2021-12-13T17:39:13.105Z",
      "defaultLanguage": 0,
      "availableLanguages": [
        0
      ]
    },
    "properties": {
      "navigation": {
        "submit": "string",
        "next": "string",
        "back": "string",
        "backVisibility": true,
        "localization": {
          "additionalProp1": {
            "submit": "string",
            "next": "string",
            "back": "string"
          },
          "additionalProp2": {
            "submit": "string",
            "next": "string",
            "back": "string"
          },
          "additionalProp3": {
            "submit": "string",
            "next": "string",
            "back": "string"
          }
        }
      },
      "campaign": {
        "header": {
          "logo": "string",
          "title": "string",
          "description": "string",
          "showQuestionsCount": true,
          "localization": {
            "additionalProp1": {
              "title": "string",
              "description": "string"
            },
            "additionalProp2": {
              "title": "string",
              "description": "string"
            },
            "additionalProp3": {
              "title": "string",
              "description": "string"
            }
          }
        },
        "footer": {
          "logo": "string",
          "title": "string",
          "description": "string",
          "showQuestionsCount": true,
          "localization": {
            "additionalProp1": {
              "title": "string",
              "description": "string"
            },
            "additionalProp2": {
              "title": "string",
              "description": "string"
            },
            "additionalProp3": {
              "title": "string",
              "description": "string"
            }
          }
        },
        "welcome": {
          "logo": "string",
          "title": "string",
          "description": "string",
          "showQuestionsCount": true,
          "localization": {
            "additionalProp1": {
              "title": "string",
              "description": "string"
            },
            "additionalProp2": {
              "title": "string",
              "description": "string"
            },
            "additionalProp3": {
              "title": "string",
              "description": "string"
            }
          }
        },
        "submissionMessage": {
          "logo": "string",
          "title": "string",
          "description": "string",
          "showQuestionsCount": true,
          "localization": {
            "additionalProp1": {
              "title": "string",
              "description": "string"
            },
            "additionalProp2": {
              "title": "string",
              "description": "string"
            },
            "additionalProp3": {
              "title": "string",
              "description": "string"
            }
          }
        }
      }
    },
    "warningMsgs": {
      "required": {
        "fieldRequired": "string",
        "oneFieldPerFormRequired": "string"
      },
      "textBox": {
        "minimumCharacterLength": "string",
        "maximumCharacterLength": "string",
        "minimumWordLength": "string",
        "maximumWordLength": "string",
        "email": "string",
        "url": "string",
        "alphapetic": "string",
        "alphaNumeric": "string",
        "numeric": "string",
        "custom": "string"
      },
      "textArea": {
        "minimumCharacterLength": "string",
        "maximumCharacterLength": "string",
        "minimumWordLength": "string",
        "maximumWordLength": "string"
      },
      "number": {
        "minimumValue": "string",
        "maximumValue": "string",
        "minimumDigits": "string",
        "maximumDigits": "string"
      },
      "email": {
        "validEmail": "string",
        "notMatchEmail": "string"
      }
    },
    "fields": [
      {
        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "templateQuestionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "type": 0,
        "parentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "order": "string",
        "properties": {
          "labelPosition": 0,
          "hidden": true,
          "label": "string",
          "sublabel": "string",
          "tooltip": "string",
          "localization": {
            "additionalProp1": {
              "label": "string",
              "sublabel": "string",
              "tooltip": "string"
            },
            "additionalProp2": {
              "label": "string",
              "sublabel": "string",
              "tooltip": "string"
            },
            "additionalProp3": {
              "label": "string",
              "sublabel": "string",
              "tooltip": "string"
            }
          }
        },
        "styles": {
          "labelStyle": {
            "color": "string",
            "backgroundColor": "string",
            "fontSize": 0,
            "weight": 0
          }
        }
      }
    ]
  }
}
```

Errors:
| Code                       | #  | Notes         |
| -------------------------- | -- | ------------- |
| `InternalServerError`      |    | Unknown Error |
| `Form:FormNotFound`        |    |               |
| `Form:LoadingTimeout`      |    |               |
