Base route: /api/Forms
This document covers the forms endpoints the admin panel should use to manage form definitions and review submissions.
Accepted values:
TextTextAreaEmailNumberDateCheckboxRadioSelect
{
"id": "guid",
"title": "string",
"description": "string | null",
"isPublished": true,
"fields": [
{
"id": "guid",
"label": "string",
"type": "Text",
"isRequired": true,
"order": 0,
"options": [
{
"id": "guid",
"label": "string",
"value": "string",
"order": 0
}
]
}
]
}{
"id": "guid",
"formId": "guid",
"userId": "string | null",
"answersJson": "string",
"created": "2026-04-18T10:30:00Z"
}The read endpoints return the shared Result<T> wrapper on success and failure.
Success example:
{
"succeeded": true,
"errors": [],
"data": []
}Failure example:
{
"succeeded": false,
"errors": ["Form not found"],
"data": null
}Create endpoints return 201 Created with the created GUID in the response body.
GET /api/Forms
No authorization required.
Response: 200 OK
{
"succeeded": true,
"errors": [],
"data": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"title": "Contact Us",
"description": "General questions and support",
"isPublished": true,
"fields": []
}
]
}GET /api/Forms/{id}
No authorization required.
Response: 200 OK
{
"succeeded": true,
"errors": [],
"data": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"title": "Contact Us",
"description": "General questions and support",
"isPublished": true,
"fields": [
{
"id": "a1111111-1111-1111-1111-111111111111",
"label": "Your name",
"type": "Text",
"isRequired": true,
"order": 0,
"options": []
}
]
}
}If the form does not exist, the API returns 400 Bad Request with:
{
"succeeded": false,
"errors": ["Form not found"],
"data": null
}POST /api/Forms
Authorization: Policies.ManageForms
Request body:
{
"title": "Volunteer Registration",
"description": "Collect volunteer details",
"isPublished": false,
"fields": [
{
"label": "Full name",
"type": "Text",
"isRequired": true,
"order": 0,
"options": []
},
{
"label": "Preferred contact method",
"type": "Select",
"isRequired": true,
"order": 1,
"options": [
{ "label": "Email", "value": "email", "order": 0 },
{ "label": "Phone", "value": "phone", "order": 1 }
]
}
]
}Response: 201 Created
"f7f6ce1d-1b7c-4c5f-b71a-6fdf6db4d0d4"The Location header points to /Forms/{createdId}.
GET /api/Forms/{formId}/submissions
Authorization: Policies.ViewForms
Response: 200 OK
{
"succeeded": true,
"errors": [],
"data": [
{
"id": "5d0e3b2c-8e1c-4f3b-9f5e-2b1e3d2e9d10",
"formId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"userId": "user-123",
"answersJson": "{\"fullName\":\"Amina Khan\",\"preferredContactMethod\":\"email\"}",
"created": "2026-04-18T10:30:00Z"
}
]
}- Use
Get all formsto populate the form list page. - Use
Get form by idto load the edit screen. - Use
Create formto save a new form definition from the builder UI. - Use
Get form submissionsto show the submissions table and the submission detail drawer. answersJsonis stored as a string; the backend does not validate its internal schema.- For options-based fields such as
SelectandRadio, send theoptionsarray in the same order the UI should display.