Skip to main content

Applicant Form API

Author: Josh S. Sakweli, Backend Lead Team Last Updated: 2025-02-17 Version: v1.0

Base URL: https://your-api-domain.com/api/v1/e-events/applicant-form

Short Description: The Applicant Form API allows event organizers to attach an optional custom multi-page form to their event. When enabled, attendees are prompted to fill in the form as part of the registration flow. The form is fully scoped to the event — all endpoints use eventId as the primary key, so the organizer never needs to track a separate formId. The entire feature is optional; if never enabled, the event registration proceeds with no form step.

Hints:

  • All endpoints require a valid Bearer token.
  • Form setup and management (enable, pages, fields, options) require the authenticated user to be the event organizer. Any other user gets 403.
  • Attendee submission endpoints (/start, /pages/{pageId}/save, /submit, /my-response) require the event to be PUBLISHED and within its registration window (registrationOpensAtregistrationClosesAt).
  • enableForm automatically creates the underlying form and a default first page — you do not create them separately.
  • startSubmission is idempotent — if the attendee already has a draft response it returns the existing one instead of creating a new one.
  • savePage saves answers for a page without advancing the page index — it is a save-in-place operation. Call submit when all pages are done.
  • Delete endpoints accept a ?hard=false query parameter. Soft delete (hard=false, default) preserves historical response data. Hard delete (hard=true) permanently removes the record.
  • DROPDOWN, RADIO, and CHECKBOX field types require options to be added separately after the field is created.
  • The HEADER field type is a display-only section divider — it has no required flag and stores no answer data.

Form Structure — Layers

┌─────────────────────────────────────────────────────────────────────────┐
│  FORM                                                                   │
│  title · description · settings · cover page                            │
│                                                                         │
│  ┌───────────────────────────────────────────────────────────────────┐  │
│  │  PAGE 1                                                           │  │
│  │  title · description · action button text                         │  │
│  │                                                                   │  │
│  │   ┌─────────────────────────────────────────────────────────┐     │  │
│  │   │ FIELD  (e.g. TEXT, EMAIL, DATE, FILE, RATING …)         │     │  │
│  │   │ label · placeholder · required · validation rules       │     │  │
│  │   └─────────────────────────────────────────────────────────┘     │  │
│  │                                                                   │  │
│  │   ┌─────────────────────────────────────────────────────────┐     │  │
│  │   │ FIELD  (DROPDOWN / RADIO / CHECKBOX)                    │     │  │
│  │   │ label · required                                        │     │  │
│  │   │   ┌──────────┐  ┌──────────┐  ┌──────────┐              │     │  │
│  │   │   │ Option 1 │  │ Option 2 │  │ Option 3 │  …           │     │  │
│  │   │   └──────────┘  └──────────┘  └──────────┘              │     │  │
│  │   └─────────────────────────────────────────────────────────┘     │  │
│  │                                                                   │  │
│  │   ┌─────────────────────────────────────────────────────────┐     │  │
│  │   │ FIELD  (HEADER — display only, no answer stored)        │     │  │
│  │   │ label (section divider text)                            │     │  │
│  │   └─────────────────────────────────────────────────────────┘     │  │
│  │                                                                   │  │
│  └───────────────────────────────────────────────────────────────────┘  │
│                                                                         │
│  ┌───────────────────────────────────────────────────────────────────┐  │
│  │  PAGE 2                                                           │  │
│  │   ┌──────────────────────────┐  ┌──────────────────────────┐      │  │
│  │   │ FIELD                    │  │ FIELD                    │  …   │  │
│  │   └──────────────────────────┘  └──────────────────────────┘      │  │
│  └───────────────────────────────────────────────────────────────────┘  │
│                                                                         │
│  ┌───────────────────────────────────────────────────────────────────┐  │
│  │  PAGE N  …                                                        │  │
│  └───────────────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────────┘

Rules at a glance:

  • A form has one or more pages displayed in displayOrder.
  • Each page has one or more fields displayed in displayOrder.
  • Fields of type DROPDOWN, RADIO, or CHECKBOX must have options added after the field is created — no other field type has options.
  • HEADER is the only field type that stores no answer and cannot be marked required. It acts purely as a section label between other fields.
  • Every other field type (TEXT, TEXTAREA, EMAIL, PHONE, NUMBER, URL, DATE, TIME, DATETIME, RATING, FILE) stores exactly one answer per attendee.

Organizer Workflow

  [Organizer]
       │
       │  POST /events/{eventId}/enable
       ▼
  ┌─────────────────────────────────────┐
  │   Form ENABLED                      │
  │   - Form auto-created internally    │
  │   - Default page auto-created       │
  │   - Config saved (displayTime etc.) │
  └──────────────┬──────────────────────┘
                 │
                 │  Build the form structure:
                 │
                 │  POST /events/{eventId}/pages
                 │  POST /events/{eventId}/pages/{pageId}/fields
                 │  POST /events/{eventId}/fields/{fieldId}/options
                 │         (DROPDOWN / RADIO / CHECKBOX only)
                 │
                 │  (Optional bulk / clone shortcuts)
                 │  POST /events/{eventId}/pages/bulk
                 │  POST /events/{eventId}/pages/{pageId}/fields/bulk
                 │  POST /events/{eventId}/pages/{pageId}/clone
                 │  POST /events/{eventId}/fields/{fieldId}/clone
                 │
                 │  Preview before publishing:
                 │  GET  /events/{eventId}/preview/metadata
                 │  GET  /events/{eventId}/preview/pages/{pageNumber}
                 │  POST /events/{eventId}/preview/pages/{pageNumber}/validate
                 ▼
  ┌─────────────────────────────────────┐
  │   Form ready — event can publish    │
  └─────────────────────────────────────┘

Attendee Submission Journey

  [Attendee — event must be PUBLISHED and within registration window]
         │
         │  POST /events/{eventId}/start
         ▼
  ┌──────────────────────────────────┐
  │  Response created (DRAFT)        │  Returns existing draft if one
  │  or existing draft returned      │  already exists (idempotent)
  └──────────────┬───────────────────┘
                 │
                 │  For each page:
                 │  PUT /events/{eventId}/pages/{pageId}/save
                 │  Body: { fieldId: { value, fileUrl, ... }, ... }
                 ▼
  ┌──────────────────────────────────┐
  │  Page answers saved              │  Save is in-place, does NOT
  │  (repeat per page)               │  advance page index automatically
  └──────────────┬───────────────────┘
                 │
                 │  POST /events/{eventId}/submit
                 ▼
  ┌──────────────────────────────────┐
  │  Response SUBMITTED              │  completionTimeSeconds recorded
  └──────────────────────────────────┘

Response Status Flow

  DRAFT ──────────────────────────────► SUBMITTED
    │                                        │
    │  (withdraw — not in this API)          │  (organizer action — outside scope)
    ▼                                        ▼
  WITHDRAWN                           UNDER_REVIEW → APPROVED / REJECTED

Standard Response Format

All API responses follow a consistent structure using the Globe Response Builder pattern.

Success Response Structure

{
  "success": true,
  "httpStatus": "OK",
  "message": "Operation completed successfully",
  "action_time": "2025-02-17T10:30:45",
  "data": { }
}

Error Response Structure

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Error description",
  "action_time": "2025-02-17T10:30:45",
  "data": "Error description"
}

Standard Response Fields

Field Type Description
success boolean true for successful operations, false for errors
httpStatus string HTTP status name (OK, CREATED, BAD_REQUEST, etc.)
message string Human-readable description of the result
action_time string ISO 8601 timestamp of when the response was generated
data object / string Response payload on success; error detail on failure

HTTP Method Badge Standards

  • GET — Green (#28a745) — Safe, read-only operations
  • POST — Blue (#007bff) — Create new resources
  • PUT — Yellow (#ffc107, black text) — Update / replace
  • PATCH — Orange (#fd7e14) — Partial update
  • DELETE — Red (#dc3545) — Remove resource

Shared Response Object Definitions

A. ApplicantFormSetupResponse

Returned only by the Enable Form endpoint (Endpoint 1).

Field Type Description
config object The saved EventApplicantFormEntity — see config fields below
config.id UUID Config record ID
config.formId UUID Internal Form Builder form ID (not needed for subsequent API calls)
config.displayTime string BEFORE_CHECKOUT or AFTER_CHECKOUT
config.isRequiredOnline boolean Whether online buyers must complete the form
config.applyToAtDoor boolean Whether walk-in attendees see the form
config.createdAt ZonedDateTime Config creation timestamp
config.updatedAt ZonedDateTime Last update timestamp
form object Full FormResponse — see FormResponse definition below

B. EventApplicantFormEntity (Config Object)

Returned by the Update Settings endpoint.

Field Type Description
id UUID Config record ID
formId UUID Internal Form Builder form ID
displayTime string BEFORE_CHECKOUT or AFTER_CHECKOUT
isRequiredOnline boolean Whether online buyers must complete the form
applyToAtDoor boolean Whether walk-in attendees see the form
createdAt ZonedDateTime ISO 8601 with offset
updatedAt ZonedDateTime ISO 8601 with offset

C. FormResponse (Full Form Object)

Field Type Description
formId UUID Form identifier (Form Builder internal ID)
title string Auto-set to "Attendee Questions - {event title}" on enable
description string Form description
settings object Form open/close settings (see FormSettings below)
settings.acceptResponses boolean Whether the form is accepting responses
settings.allowMultipleSubmissions boolean Whether a user can submit more than once
settings.responseStartTime Instant UTC datetime when responses open
settings.responseDeadline Instant UTC datetime when responses close
settings.allowSaveDraft boolean Whether respondents can save progress
coverPage object Optional cover page config
createdBy string Username of creator
createdAt LocalDateTime Creation timestamp
pages[] array Ordered list of PageResponse objects

D. PageResponse

Field Type Description
pageId UUID Page identifier
title string Page heading shown to attendee
description string Subheading or instruction text
displayOrder integer 1-based position within the form
actionButtonText string Label for the next/submit button
fields[] array Ordered list of FieldResponse objects (soft-deleted excluded)

E. FieldResponse

Field Type Description
fieldId UUID Field identifier
type string TEXT, TEXTAREA, EMAIL, PHONE, NUMBER, URL, DATE, TIME, DATETIME, DROPDOWN, RADIO, CHECKBOX, FILE, RATING, HEADER
label string Field label. For HEADER type this is the section title
description string Helper text shown below the field
placeholder string Input placeholder text
displayOrder integer 1-based order within the page
required boolean Whether the field must be answered. Always false for HEADER
validation object See FieldValidation below
options[] array OptionResponse entries — only for DROPDOWN, RADIO, CHECKBOX

FieldValidation Object

Field Applicable To Description
minLength / maxLength TEXT, TEXTAREA Character count constraints
pattern / patternMessage TEXT Regex pattern and custom error message
min / max NUMBER Numeric range
minDate / maxDate DATE Date range (YYYY-MM-DD)
minSelections / maxSelections CHECKBOX Selection count constraints
maxSizeMb / accept FILE File size limit and accepted MIME types

F. OptionResponse

Field Type Description
optionId UUID Option identifier
label string Display label shown to attendee
displayOrder integer 1-based order within the field

G. FormResponseObject (Attendee Submission)

Field Type Description
responseId UUID Unique response identifier
formId UUID Internal form ID
submittedBy string Username of the attendee
status string DRAFT, SUBMITTED, UNDER_REVIEW, APPROVED, REJECTED, WITHDRAWN
completedPageIds array UUIDs of pages marked complete
currentPageIndex integer 0-based index of current page
startedAt LocalDateTime When the attendee started the form
submittedAt LocalDateTime When the response was submitted
completionTimeSeconds integer Total seconds from start to submit
answers[] array See AnswerResponse below

AnswerResponse

Field Type Description
answerId UUID Answer identifier
fieldId UUID Field ID (null if field was hard-deleted)
fieldLabel string Label snapshot — preserved even if field is later deleted
fieldType string Type snapshot — preserved even if field is later deleted
fieldDeleted boolean true when the source field has been soft-deleted
value any Submitted value. String for text/single-choice, array of strings for checkbox, number for NUMBER/RATING
answeredAt LocalDateTime When this answer was saved
fileUrl / fileName / fileSize / fileType various File upload metadata (FILE fields only)

H. BulkOperationResult

Field Type Description
successCount integer Number of items successfully processed
failureCount integer Number of items that failed
errors[] array Error message per failed item
createdFields[] array FieldResponse objects (bulk field operations)
createdPages[] array PageResponse objects (bulk page operations)

I. BulkDeleteResult

Field Type Description
successCount integer Number of items successfully deleted
failureCount integer Number of items that failed
errors[] array Error message per failed item
deletedIds[] array UUIDs of successfully deleted items

J. FormAnalytics

Field Type Description
formId UUID Form identifier
formTitle string Form title
stats.totalStarted integer Total responses started (including drafts)
stats.totalDrafts integer Responses still in DRAFT
stats.totalSubmitted integer Responses with SUBMITTED status
stats.totalWithdrawn integer Withdrawn responses
stats.completionRate double Submitted / totalStarted × 100
stats.dropOffRate double Inverse of completion rate
stats.avgCompletionTimeSeconds double Mean time from start to submit
stats.fastestTimeSeconds integer Fastest submission time
stats.slowestTimeSeconds integer Slowest submission time
fieldAnalytics[] array Per-field breakdown
fieldAnalytics[].fieldId UUID Field ID
fieldAnalytics[].fieldLabel string Field label snapshot
fieldAnalytics[].fieldType string Field type snapshot
fieldAnalytics[].fieldDeleted boolean Whether field is soft-deleted
fieldAnalytics[].totalResponses integer Total answers for this field
fieldAnalytics[].choiceDistribution[] array { option, count, percentage } — choice fields
fieldAnalytics[].numericStats object { min, max, avg, median } — NUMBER/RATING fields
fieldAnalytics[].textResponses[] array Raw text answers — TEXT/TEXTAREA fields
dailySubmissions[] array { date, count } — submissions per day

Standard Error Types

Application-Level Exceptions (400–499)

  • 400 BAD_REQUEST — Form already enabled for this event, field type does not support options, already submitted
  • 401 UNAUTHORIZED — Missing, expired, or malformed Bearer token
  • 403 FORBIDDEN — Authenticated but not the event organizer; or registration window not open/already closed
  • 404 NOT_FOUND — Event not found, form not enabled, page/field/option not found, no response found
  • 422 UNPROCESSABLE_ENTITY — Bean validation failures, required field missing on save

Server-Level Exceptions (500+)

  • 500 INTERNAL_SERVER_ERROR — Unexpected runtime error

Shared Error Response Examples

401 — Unauthorized:

{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "Token has expired",
  "action_time": "2025-02-17T10:30:45",
  "data": "Token has expired"
}

403 — Forbidden (not organizer):

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Only organizer can manage form",
  "action_time": "2025-02-17T10:30:45",
  "data": "Only organizer can manage form"
}

403 — Forbidden (registration closed):

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Registration closed",
  "action_time": "2025-02-17T10:30:45",
  "data": "Registration closed"
}

404 — Form not enabled:

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Form not enabled",
  "action_time": "2025-02-17T10:30:45",
  "data": "Form not enabled"
}

Endpoints


Form Setup


1. Enable Applicant Form

Purpose: Enables the applicant form for an event. Internally creates a Form Builder form titled "Attendee Questions - {event title}" and an initial default page titled "Attendee Information". Only the event organizer can call this. Returns the full form structure alongside the config.

Endpoint: POST /api/v1/e-events/applicant-form/events/{eventId}/enable

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event to enable the form for Must be a valid UUID

Request JSON Sample:

{
  "displayTime": "BEFORE_CHECKOUT",
  "isRequiredOnline": true,
  "applyToAtDoor": false
}

Request Body Parameters:

Parameter Type Required Description Validation
displayTime string No When attendees see the form in the UI flow Enum: BEFORE_CHECKOUT, AFTER_CHECKOUT. Defaults to BEFORE_CHECKOUT
isRequiredOnline boolean No Whether online ticket buyers must complete the form before proceeding Defaults to false
applyToAtDoor boolean No Whether at-door / walk-in attendees also see the form Defaults to false

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "CREATED",
  "message": "Applicant form enabled with default page",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "config": {
      "id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
      "formId": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
      "displayTime": "BEFORE_CHECKOUT",
      "isRequiredOnline": true,
      "applyToAtDoor": false,
      "createdAt": "2025-02-17T10:30:45+03:00",
      "updatedAt": null
    },
    "form": {
      "formId": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
      "title": "Attendee Questions - Dar es Salaam Jazz Festival 2025",
      "description": null,
      "settings": null,
      "coverPage": null,
      "createdBy": "amina.hassan",
      "createdAt": "2025-02-17T10:30:45",
      "pages": [
        {
          "pageId": "1a2b3c4d-...",
          "title": "Attendee Information",
          "description": "Please provide your details",
          "displayOrder": 1,
          "actionButtonText": "Next",
          "fields": []
        }
      ]
    }
  }
}

Success Response Fields: data is an ApplicantFormSetupResponse.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer, or form is already enabled for this event
404 Event not found

2. Update Form Settings

Purpose: Updates the form configuration for the event — displayTime, isRequiredOnline, and applyToAtDoor. Does not affect the form structure (pages/fields). All fields are optional.

Endpoint: PUT /api/v1/e-events/applicant-form/events/{eventId}/settings

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID

Request JSON Sample:

{
  "displayTime": "AFTER_CHECKOUT",
  "isRequiredOnline": false,
  "applyToAtDoor": true
}

Request Body Parameters:

Parameter Type Required Description Validation
displayTime string No Updated display time Enum: BEFORE_CHECKOUT, AFTER_CHECKOUT
isRequiredOnline boolean No Updated required flag for online buyers
applyToAtDoor boolean No Updated at-door flag

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Form settings updated",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
    "formId": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
    "displayTime": "AFTER_CHECKOUT",
    "isRequiredOnline": false,
    "applyToAtDoor": true,
    "createdAt": "2025-02-17T10:30:45+03:00",
    "updatedAt": "2025-02-17T11:00:00+03:00"
  }
}

Success Response Fields: data is an EventApplicantFormEntity config object.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or form not enabled

3. Disable Form

Purpose: Disables and permanently removes the applicant form from the event. The underlying Form Builder form is soft-deleted. Existing submitted responses are preserved. This action cannot be undone — to re-enable a form, call Endpoint 1 again which will create a fresh form.

Endpoint: DELETE /api/v1/e-events/applicant-form/events/{eventId}/disable

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Applicant form disabled",
  "action_time": "2025-02-17T10:30:45",
  "data": null
}

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or form not enabled

Page Management


4. Add Page

Purpose: Appends a new blank page to the form. displayOrder is auto-assigned as the next position. Fields are added to the page separately.

Endpoint: POST /api/v1/e-events/applicant-form/events/{eventId}/pages

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID

Request JSON Sample:

{
  "title": "Emergency Contact",
  "description": "In case we need to reach someone on your behalf.",
  "actionButtonText": "Next"
}

Request Body Parameters:

Parameter Type Required Description Validation
title string Yes Page heading shown to attendee Max: 255 characters
description string No Subheading or instruction text Max: 500 characters
actionButtonText string No Label for the page's action button Max: 50 characters

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "CREATED",
  "message": "Page added",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "pageId": "2b3c4d5e-f6a7-8b9c-0d1e-2f3a4b5c6d7e",
    "title": "Emergency Contact",
    "description": "In case we need to reach someone on your behalf.",
    "displayOrder": 2,
    "actionButtonText": "Next",
    "fields": []
  }
}

Success Response Fields: data is a PageResponse.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or form not enabled
422 title is blank

5. Update Page

Purpose: Updates the title, description, or action button label of an existing page.

Endpoint: PUT /api/v1/e-events/applicant-form/events/{eventId}/pages/{pageId}

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
pageId UUID Yes The page to update Must be a valid UUID

Request JSON Sample:

{
  "title": "Your Background",
  "actionButtonText": "Continue"
}

Request Body Parameters:

Parameter Type Required Description Validation
title string No Updated page title Max: 255 characters
description string No Updated description Max: 500 characters
actionButtonText string No Updated button label Max: 50 characters

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Page updated",
  "action_time": "2025-02-17T10:30:45",
  "data": { "...": "PageResponse object" }
}

Success Response Fields: data is a PageResponse.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or page not found

6. Delete Page

Purpose: Deletes a page. Pass ?hard=false (default) for soft delete — the page is hidden but historical answer data is preserved. Pass ?hard=true to permanently remove the page and all its fields.

Endpoint: DELETE /api/v1/e-events/applicant-form/events/{eventId}/pages/{pageId}

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
pageId UUID Yes The page to delete Must be a valid UUID

Query Parameters:

Parameter Type Required Description Validation Default
hard boolean No true = permanent delete, false = soft delete false

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Page deleted",
  "action_time": "2025-02-17T10:30:45",
  "data": null
}

When hard=true, message is "Page permanently deleted".

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or page not found

7. Bulk Add Pages (with Fields)

Purpose: Creates multiple pages in one call. Each page can optionally include an inline list of fields.

Endpoint: POST /api/v1/e-events/applicant-form/events/{eventId}/pages/bulk

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID

Request JSON Sample:

{
  "pages": [
    {
      "title": "Personal Details",
      "actionButtonText": "Next",
      "fields": [
        { "type": "TEXT", "label": "Full Name", "required": true },
        { "type": "EMAIL", "label": "Email", "required": true }
      ]
    },
    {
      "title": "Dietary Requirements",
      "actionButtonText": "Submit",
      "fields": [
        { "type": "DROPDOWN", "label": "Dietary preference", "required": false }
      ]
    }
  ]
}

Request Body Parameters:

Parameter Type Required Description Validation
pages array Yes Pages to create Min 1 item
pages[].title string Yes Page title Max: 255 characters
pages[].description string No Page description Max: 500 characters
pages[].actionButtonText string No Button label Max: 50 characters
pages[].fields array No Fields to create inline See CreateField below
pages[].fields[].type string Yes Field type See FieldType enum
pages[].fields[].label string Yes Field label Max: 255 characters
pages[].fields[].description string No Helper text Max: 500 characters
pages[].fields[].placeholder string No Placeholder text Max: 255 characters
pages[].fields[].required boolean No Required flag Defaults to false
pages[].fields[].validation object No Validation rules See FieldValidation

Note: For DROPDOWN, RADIO, and CHECKBOX fields created via bulk, options must still be added separately using the option endpoints after this call.

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "CREATED",
  "message": "2 pages added, 0 failed",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "successCount": 2,
    "failureCount": 0,
    "errors": [],
    "createdPages": [
      { "...": "PageResponse for page 1" },
      { "...": "PageResponse for page 2" }
    ]
  }
}

Success Response Fields: data is a BulkOperationResult.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or form not enabled

8. Bulk Delete Pages

Purpose: Deletes multiple pages in one call. Supports both soft delete (default) and hard delete via ?hard query param. Items are processed individually — a failure on one does not stop the rest.

Endpoint: DELETE /api/v1/e-events/applicant-form/events/{eventId}/pages/bulk

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID

Query Parameters:

Parameter Type Required Description Validation Default
hard boolean No true = permanent delete false

Request JSON Sample:

{
  "ids": ["pageId-1", "pageId-2"]
}

Request Body Parameters:

Parameter Type Required Description Validation
ids array Yes UUIDs of pages to delete Min 1 item

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "2 pages deleted, 0 failed",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "successCount": 2,
    "failureCount": 0,
    "errors": [],
    "deletedIds": ["pageId-1", "pageId-2"]
  }
}

Success Response Fields: data is a BulkDeleteResult.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found. Individual page errors reported in data.errors[]

9. Clone Page

Purpose: Creates an exact copy of an existing page including all its active fields and options. The clone is appended at the end of the form with "(Copy)" added to the title.

Endpoint: POST /api/v1/e-events/applicant-form/events/{eventId}/pages/{pageId}/clone

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
pageId UUID Yes The page to clone Must be a valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "CREATED",
  "message": "Page cloned successfully",
  "action_time": "2025-02-17T10:30:45",
  "data": { "...": "PageResponse for the cloned page" }
}

Success Response Fields: data is a PageResponse for the new clone.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or page not found

Field Management


10. Add Field

Purpose: Adds a single field to a page. displayOrder is auto-assigned. For DROPDOWN, RADIO, and CHECKBOX types, options must be added separately after this call.

Endpoint: POST /api/v1/e-events/applicant-form/events/{eventId}/pages/{pageId}/fields

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
pageId UUID Yes The page to add the field to Must be a valid UUID

Request JSON Sample:

{
  "type": "TEXT",
  "label": "Full Name",
  "description": "As it appears on your ID.",
  "placeholder": "e.g. Amina Hassan",
  "required": true,
  "validation": {
    "minLength": 2,
    "maxLength": 100
  }
}

Request Body Parameters:

Parameter Type Required Description Validation
type string Yes Field type Enum: TEXT, TEXTAREA, EMAIL, PHONE, NUMBER, URL, DATE, TIME, DATETIME, DROPDOWN, RADIO, CHECKBOX, FILE, RATING, HEADER
label string Yes Field label (or section title for HEADER) Max: 255 characters
description string No Helper text Max: 500 characters
placeholder string No Input placeholder Max: 255 characters
required boolean No Required flag. Forced false for HEADER Defaults to false
validation object No Validation rules See FieldValidation

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "CREATED",
  "message": "Field added",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "fieldId": "c3d4e5f6-a7b8-9c0d-1e2f-3a4b5c6d7e8f",
    "type": "TEXT",
    "label": "Full Name",
    "description": "As it appears on your ID.",
    "placeholder": "e.g. Amina Hassan",
    "displayOrder": 1,
    "required": true,
    "validation": { "minLength": 2, "maxLength": 100 },
    "options": []
  }
}

Success Response Fields: data is a FieldResponse.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or page not found
422 type is null, or label is blank

11. Update Field

Purpose: Updates the configuration of an existing field. All fields are optional.

Endpoint: PUT /api/v1/e-events/applicant-form/events/{eventId}/fields/{fieldId}

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
fieldId UUID Yes The field to update Must be a valid UUID

Request JSON Sample:

{
  "label": "Legal Full Name",
  "required": true,
  "validation": {
    "minLength": 3,
    "maxLength": 150
  }
}

Request Body Parameters:

Parameter Type Required Description Validation
type string No Updated field type See FieldType enum
label string No Updated label Max: 255 characters
description string No Updated helper text Max: 500 characters
placeholder string No Updated placeholder Max: 255 characters
required boolean No Updated required flag. Forced false if type is HEADER
validation object No Updated validation rules (full replacement) See FieldValidation

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Field updated",
  "action_time": "2025-02-17T10:30:45",
  "data": { "...": "FieldResponse object" }
}

Success Response Fields: data is a FieldResponse.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or field not found

12. Delete Field

Purpose: Deletes a field. Soft delete (default) preserves historical answer snapshots. Hard delete permanently removes the field record.

Endpoint: DELETE /api/v1/e-events/applicant-form/events/{eventId}/fields/{fieldId}

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
fieldId UUID Yes The field to delete Must be a valid UUID

Query Parameters:

Parameter Type Required Description Validation Default
hard boolean No true = permanent delete false

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Field deleted",
  "action_time": "2025-02-17T10:30:45",
  "data": null
}

When hard=true, message is "Field permanently deleted".

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or field not found

13. Bulk Add Fields

Purpose: Adds multiple fields to a page in one call. Fields are appended after existing fields in array order.

Endpoint: POST /api/v1/e-events/applicant-form/events/{eventId}/pages/{pageId}/fields/bulk

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
pageId UUID Yes The page to add fields to Must be a valid UUID

Request JSON Sample:

{
  "fields": [
    { "type": "EMAIL", "label": "Email Address", "required": true },
    { "type": "PHONE", "label": "Phone Number", "required": false },
    { "type": "HEADER", "label": "Travel Details" },
    { "type": "DROPDOWN", "label": "Arrival method", "required": false }
  ]
}

Request Body Parameters:

Parameter Type Required Description Validation
fields array Yes Fields to create Min 1 item
fields[].type string Yes Field type See FieldType enum
fields[].label string Yes Field label Max: 255 characters
fields[].description string No Helper text Max: 500 characters
fields[].placeholder string No Placeholder text Max: 255 characters
fields[].required boolean No Required flag Defaults to false
fields[].validation object No Validation rules See FieldValidation

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "CREATED",
  "message": "4 fields added, 0 failed",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "successCount": 4,
    "failureCount": 0,
    "errors": [],
    "createdFields": [ "[ FieldResponse objects ]" ]
  }
}

Success Response Fields: data is a BulkOperationResult.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or page not found

14. Bulk Delete Fields

Purpose: Deletes multiple fields from a page in one call. Supports soft and hard delete via ?hard.

Endpoint: DELETE /api/v1/e-events/applicant-form/events/{eventId}/pages/{pageId}/fields/bulk

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
pageId UUID Yes The page containing the fields Must be a valid UUID

Query Parameters:

Parameter Type Required Description Validation Default
hard boolean No true = permanent delete false

Request JSON Sample:

{
  "ids": ["fieldId-1", "fieldId-2"]
}

Request Body Parameters:

Parameter Type Required Description Validation
ids array Yes UUIDs of fields to delete Min 1 item

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "2 fields deleted, 0 failed",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "successCount": 2,
    "failureCount": 0,
    "errors": [],
    "deletedIds": ["fieldId-1", "fieldId-2"]
  }
}

Success Response Fields: data is a BulkDeleteResult.

Possible Error Responses: Same as Endpoint 8 (401, 403, 404).


15. Bulk Update Fields

Purpose: Updates required flag and/or validation rules across multiple fields at once.

Endpoint: PATCH /api/v1/e-events/applicant-form/events/{eventId}/fields/bulk

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID

Request JSON Sample:

{
  "fieldIds": ["fieldId-1", "fieldId-2"],
  "required": true,
  "validation": { "maxLength": 200 }
}

Request Body Parameters:

Parameter Type Required Description Validation
fieldIds array Yes UUIDs of fields to update Min 1 item
required boolean No New required value for all listed fields
validation object No New validation rules for all listed fields (full replacement) See FieldValidation

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "2 fields updated, 0 failed",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "successCount": 2,
    "failureCount": 0,
    "errors": [],
    "createdFields": [ "[ Updated FieldResponse objects ]" ]
  }
}

Success Response Fields: data is a BulkOperationResult.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 One or more field IDs not found — reported in data.errors[]

16. Clone Field

Purpose: Creates a copy of a field (with its options) and appends it to a target page. Label gets "(Copy)" appended.

Endpoint: POST /api/v1/e-events/applicant-form/events/{eventId}/fields/{fieldId}/clone

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
fieldId UUID Yes The field to clone Must be a valid UUID

Query Parameters:

Parameter Type Required Description Validation Default
targetPageId UUID Yes The page to clone the field into Must be a valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "CREATED",
  "message": "Field cloned successfully",
  "action_time": "2025-02-17T10:30:45",
  "data": { "...": "FieldResponse for the cloned field" }
}

Success Response Fields: data is a FieldResponse for the new clone.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found, field not found, or target page not found

Option Management


17. Add Option

Purpose: Adds a choice option to a DROPDOWN, RADIO, or CHECKBOX field. Calling this on any other field type returns 400.

Endpoint: POST /api/v1/e-events/applicant-form/events/{eventId}/fields/{fieldId}/options

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
fieldId UUID Yes The field to add an option to Must be DROPDOWN, RADIO, or CHECKBOX type

Request JSON Sample:

{
  "label": "By Car"
}

Request Body Parameters:

Parameter Type Required Description Validation
label string Yes Display label for this option Max: 255 characters

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "CREATED",
  "message": "Option added",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "optionId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a",
    "label": "By Car",
    "displayOrder": 1
  }
}

Success Response Fields: data is an OptionResponse.

Possible Error Responses:

Status Scenario
401 No or expired token
400 Field type does not support options
403 Not the event organizer
404 Event not found or field not found
422 label is blank

18. Update Option

Purpose: Updates the label of an existing option.

Endpoint: PUT /api/v1/e-events/applicant-form/events/{eventId}/options/{optionId}

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
optionId UUID Yes The option to update Must be a valid UUID

Request JSON Sample:

{
  "label": "Public Transport"
}

Request Body Parameters:

Parameter Type Required Description Validation
label string No Updated label Max: 255 characters

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Option updated",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "optionId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a",
    "label": "Public Transport",
    "displayOrder": 1
  }
}

Success Response Fields: data is an OptionResponse.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or option not found

19. Delete Option

Purpose: Deletes an option. Soft delete (default) preserves previously selected answer values. Hard delete permanently removes the option record.

Endpoint: DELETE /api/v1/e-events/applicant-form/events/{eventId}/options/{optionId}

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
optionId UUID Yes The option to delete Must be a valid UUID

Query Parameters:

Parameter Type Required Description Validation Default
hard boolean No true = permanent delete false

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Option deleted",
  "action_time": "2025-02-17T10:30:45",
  "data": null
}

When hard=true, message is "Option permanently deleted".

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or option not found

20. Bulk Delete Options

Purpose: Deletes multiple options from a field in one call. Supports soft and hard delete via ?hard.

Endpoint: DELETE /api/v1/e-events/applicant-form/events/{eventId}/fields/{fieldId}/options/bulk

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
fieldId UUID Yes The field containing the options Must be a valid UUID

Query Parameters:

Parameter Type Required Description Validation Default
hard boolean No true = permanent delete false

Request JSON Sample:

{
  "ids": ["optionId-1", "optionId-2"]
}

Request Body Parameters:

Parameter Type Required Description Validation
ids array Yes UUIDs of options to delete Min 1 item

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "2 options deleted, 0 failed",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "successCount": 2,
    "failureCount": 0,
    "errors": [],
    "deletedIds": ["optionId-1", "optionId-2"]
  }
}

Success Response Fields: data is a BulkDeleteResult.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or field not found. Individual errors in data.errors[]

21. Bulk Update Options

Purpose: Updates the labels of multiple options in one call.

Endpoint: PATCH /api/v1/e-events/applicant-form/events/{eventId}/options/bulk

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID

Request JSON Sample:

{
  "options": [
    { "optionId": "optionId-1", "label": "Train" },
    { "optionId": "optionId-2", "label": "Bus" }
  ]
}

Request Body Parameters:

Parameter Type Required Description Validation
options array Yes List of option updates Min 1 item
options[].optionId UUID Yes The option to update Must be a valid UUID
options[].label string No New label Max: 255 characters

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "2 options updated, 0 failed",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "successCount": 2,
    "failureCount": 0,
    "errors": []
  }
}

Success Response Fields: data is a BulkOperationResult.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 An option ID not found — reported in data.errors[]

Preview


22. Get Preview Metadata

Purpose: Returns a lightweight summary of the form structure — total pages, page numbers, and titles — without loading full field data. Used to render a progress indicator before the attendee starts filling.

Endpoint: GET /api/v1/e-events/applicant-form/events/{eventId}/preview/metadata

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Metadata retrieved",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "formId": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
    "formTitle": "Attendee Questions - Dar es Salaam Jazz Festival 2025",
    "totalPages": 3,
    "pageNumbers": [
      { "pageNumber": 1, "pageTitle": "Attendee Information" },
      { "pageNumber": 2, "pageTitle": "Emergency Contact" },
      { "pageNumber": 3, "pageTitle": "Dietary Requirements" }
    ]
  }
}

Success Response Fields:

Field Description
formId Internal form ID
formTitle Form title
totalPages Total active pages
pageNumbers[].pageNumber 1-based page number
pageNumbers[].pageTitle Page heading

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or form not enabled

23. Preview Page by Number

Purpose: Returns a specific page by its 1-based position number, including all its active fields and options. Allows the organizer to preview what attendees will see before publishing.

Endpoint: GET /api/v1/e-events/applicant-form/events/{eventId}/preview/pages/{pageNumber}

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
pageNumber integer Yes 1-based page position Must be ≥ 1 and ≤ total active pages

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Preview page retrieved",
  "action_time": "2025-02-17T10:30:45",
  "data": { "...": "PageResponse object" }
}

Success Response Fields: data is a PageResponse.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found, form not enabled, or pageNumber out of range

24. Validate Preview Page Answers

Purpose: Runs validation on a set of answers for a specific page number without creating or saving any data. Lets the organizer test field validation rules before the form goes live.

Endpoint: POST /api/v1/e-events/applicant-form/events/{eventId}/preview/pages/{pageNumber}/validate

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
pageNumber integer Yes 1-based page number to validate against Must be ≥ 1 and ≤ total active pages

Request JSON Sample:

{
  "fieldId-fullname": { "value": "" },
  "fieldId-email":    { "value": "not-an-email" }
}

Request Body: A flat map of fieldId (UUID) → AnswerValue. AnswerValue has value (any), plus optional fileUrl, fileName, fileSize, fileType for FILE fields.

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Validation complete",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "valid": false,
    "errors": [
      {
        "pageId": "1a2b3c4d-...",
        "pageTitle": "Attendee Information",
        "fieldId": "fieldId-fullname",
        "fieldLabel": "Full Name",
        "errorMessage": "Full Name is required",
        "errorType": "REQUIRED"
      },
      {
        "pageId": "1a2b3c4d-...",
        "pageTitle": "Attendee Information",
        "fieldId": "fieldId-email",
        "fieldLabel": "Email",
        "errorMessage": "Email must be valid email",
        "errorType": "INVALID_FORMAT"
      }
    ]
  }
}

Success Response Fields:

Field Description
data.valid true if all fields passed validation
data.errors[].pageId Page UUID
data.errors[].pageTitle Page title
data.errors[].fieldId Field UUID
data.errors[].fieldLabel Field label
data.errors[].errorMessage Human-readable error
data.errors[].errorType REQUIRED, INVALID_FORMAT, INVALID_TYPE, VALIDATION_FAILED

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found, form not enabled, or pageNumber out of range

Attendee Submission


25. Start Submission

Purpose: Initiates the attendee's form response session. Creates a new DRAFT response tied to this event's form. If the attendee already has a draft or submitted response for this event's form, the existing response is returned — this endpoint is idempotent. Requires the event to be PUBLISHED and within its registration window.

Endpoint: POST /api/v1/e-events/applicant-form/events/{eventId}/start

Access Level: 🔒 Protected (Any authenticated attendee)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The published event Must be a valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Form submission started",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "responseId": "e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9a0b",
    "formId": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
    "submittedBy": "john.doe",
    "status": "DRAFT",
    "completedPageIds": [],
    "currentPageIndex": 0,
    "startedAt": "2025-02-17T10:30:45",
    "submittedAt": null,
    "completionTimeSeconds": null,
    "answers": []
  }
}

Success Response Fields: data is a FormResponseObject.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Event not published, registration not yet open, or registration already closed
404 Event not found or form not enabled

26. Save Page Answers

Purpose: Saves the attendee's answers for a specific page. Can be called multiple times — each call replaces the previous answers for that page. This is a save-in-place operation; it does not advance the page index. Call submit (Endpoint 28) when all pages are complete.

Endpoint: PUT /api/v1/e-events/applicant-form/events/{eventId}/pages/{pageId}/save

Access Level: 🔒 Protected (Attendee — response owner)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
pageId UUID Yes The page being answered Must be a valid UUID belonging to this event's form

Request JSON Sample:

{
  "c3d4e5f6-a7b8-9c0d-1e2f-3a4b5c6d7e8f": {
    "value": "Amina Hassan"
  },
  "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a": {
    "value": "amina@example.com"
  },
  "e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9a0b": {
    "value": "optionId-bycar"
  },
  "f6a7b8c9-d0e1-2f3a-4b5c-6d7e8f9a0b1c": {
    "value": null,
    "fileUrl": "https://cdn.example.com/uploads/id.pdf",
    "fileName": "national-id.pdf",
    "fileSize": 204800,
    "fileType": "application/pdf"
  }
}

Request Body: A flat Map<UUID, AnswerValue> where each key is a fieldId.

Key Type Description
{fieldId} UUID (map key) The field being answered
.value any Answer value. See answer value types below
.fileUrl string FILE fields — uploaded file URL
.fileName string FILE fields — original file name
.fileSize long FILE fields — file size in bytes
.fileType string FILE fields — MIME type

Answer Value Types

Field Type Expected Value
TEXT, TEXTAREA, EMAIL, PHONE, URL String
NUMBER Number (integer or decimal)
DATE String — YYYY-MM-DD
TIME String — HH:mm
DATETIME String — ISO 8601 datetime
DROPDOWN, RADIO String — UUID of selected option
CHECKBOX Array of strings — UUIDs of selected options
RATING Integer — 1 to 5
FILE null — metadata goes in fileUrl, fileName, etc.
HEADER Omit entirely — no answer needed

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Page saved",
  "action_time": "2025-02-17T10:30:45",
  "data": { "...": "Full FormResponseObject with updated answers" }
}

Success Response Fields: data is a FormResponseObject reflecting the updated answer state.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Registration window closed or event not published
404 Event not found, form not enabled, or no active draft found — call /start first
422 A required field has no value

27. Get My Response

Purpose: Returns the authenticated attendee's current response for the event's form — whether still in draft or already submitted.

Endpoint: GET /api/v1/e-events/applicant-form/events/{eventId}/my-response

Access Level: 🔒 Protected (Any authenticated attendee)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Response retrieved",
  "action_time": "2025-02-17T10:30:45",
  "data": { "...": "Full FormResponseObject" }
}

Success Response Fields: data is a FormResponseObject.

Possible Error Responses:

Status Scenario
401 No or expired token
404 No response found for this attendee on this event's form

28. Submit

Purpose: Finalises and submits the attendee's response. The system validates all pages before accepting. Sets status to SUBMITTED and records completionTimeSeconds.

Endpoint: POST /api/v1/e-events/applicant-form/events/{eventId}/submit

Access Level: 🔒 Protected (Attendee — response owner)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Form submitted successfully",
  "action_time": "2025-02-17T10:30:45",
  "data": { "...": "Full FormResponseObject with status SUBMITTED" }
}

Success Response Fields: data is a FormResponseObject. data.status will be "SUBMITTED".

Possible Error Responses:

Status Scenario
401 No or expired token
403 Already submitted, or registration window closed
404 Event not found, form not enabled, or no draft response found
422 Required fields on one or more pages are unanswered

Organizer Response Management


29. Get Response by ID

Purpose: Retrieves a specific attendee response by ID. Available to the event organizer only.

Endpoint: GET /api/v1/e-events/applicant-form/events/{eventId}/responses/{responseId}

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID
responseId UUID Yes The response to retrieve Must be a valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Response retrieved",
  "action_time": "2025-02-17T10:30:45",
  "data": { "...": "Full FormResponseObject" }
}

Success Response Fields: data is a FormResponseObject.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or response not found

30. Get All Responses

Purpose: Returns a paginated list of all attendee responses for the event's form. For organizer review and export.

Endpoint: GET /api/v1/e-events/applicant-form/events/{eventId}/responses

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID

Query Parameters:

Parameter Type Required Description Validation Default
page integer No Page number (0-based) Min: 0 0
size integer No Items per page Min: 1 20

Note: This endpoint uses 0-based pagination (page=0 is the first page), matching the Spring Pageable default passed from the controller.

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Responses retrieved",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "content": [ "[ FormResponseObject entries ]" ],
    "totalElements": 48,
    "totalPages": 3,
    "first": true,
    "last": false,
    "empty": false
  }
}

Success Response Fields: data.content[] contains FormResponseObject entries.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or form not enabled

31. Get Analytics

Purpose: Returns full submission analytics for the event's form — stats overview, per-field distributions, and daily submission trends.

Endpoint: GET /api/v1/e-events/applicant-form/events/{eventId}/analytics

Access Level: 🔒 Protected (Event organizer only)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
eventId UUID Yes The event Must be a valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Analytics retrieved",
  "action_time": "2025-02-17T10:30:45",
  "data": {
    "formId": "9f1a2b3c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
    "formTitle": "Attendee Questions - Dar es Salaam Jazz Festival 2025",
    "stats": {
      "totalStarted": 120,
      "totalDrafts": 18,
      "totalSubmitted": 95,
      "totalWithdrawn": 7,
      "completionRate": 79.2,
      "dropOffRate": 20.8,
      "avgCompletionTimeSeconds": 312.0,
      "fastestTimeSeconds": 45,
      "slowestTimeSeconds": 1890
    },
    "fieldAnalytics": [
      {
        "fieldId": "c3d4e5f6-...",
        "fieldLabel": "Full Name",
        "fieldType": "TEXT",
        "fieldDeleted": false,
        "totalResponses": 95,
        "uniqueResponses": 95,
        "textResponses": ["Amina Hassan", "John Doe", "..."]
      },
      {
        "fieldId": "e5f6a7b8-...",
        "fieldLabel": "Arrival method",
        "fieldType": "DROPDOWN",
        "fieldDeleted": false,
        "totalResponses": 95,
        "choiceDistribution": [
          { "option": "By Car", "count": 42, "percentage": 44.2 },
          { "option": "Public Transport", "count": 35, "percentage": 36.8 },
          { "option": "On Foot", "count": 18, "percentage": 18.9 }
        ]
      }
    ],
    "dailySubmissions": [
      { "date": "2025-07-15", "count": 12 },
      { "date": "2025-07-16", "count": 28 }
    ]
  }
}

Success Response Fields: data is a FormAnalytics.

Possible Error Responses:

Status Scenario
401 No or expired token
403 Not the event organizer
404 Event not found or form not enabled

Quick Reference — Endpoint Summary

# Method Path Auth Who Description
Form Setup
1 POST /events/{eventId}/enable 🔒 Organizer Enable form + create default page
2 PUT /events/{eventId}/settings 🔒 Organizer Update form display settings
3 DELETE /events/{eventId}/disable 🔒 Organizer Disable and remove form
Page Management
4 POST /events/{eventId}/pages 🔒 Organizer Add a page
5 PUT /events/{eventId}/pages/{pageId} 🔒 Organizer Update a page
6 DELETE /events/{eventId}/pages/{pageId}?hard=false 🔒 Organizer Delete a page (soft or hard)
7 POST /events/{eventId}/pages/bulk 🔒 Organizer Bulk add pages with fields
8 DELETE /events/{eventId}/pages/bulk?hard=false 🔒 Organizer Bulk delete pages
9 POST /events/{eventId}/pages/{pageId}/clone 🔒 Organizer Clone a page
Field Management
10 POST /events/{eventId}/pages/{pageId}/fields 🔒 Organizer Add a field to a page
11 PUT /events/{eventId}/fields/{fieldId} 🔒 Organizer Update a field
12 DELETE /events/{eventId}/fields/{fieldId}?hard=false 🔒 Organizer Delete a field (soft or hard)
13 POST /events/{eventId}/pages/{pageId}/fields/bulk 🔒 Organizer Bulk add fields
14 DELETE /events/{eventId}/pages/{pageId}/fields/bulk?hard=false 🔒 Organizer Bulk delete fields
15 PATCH /events/{eventId}/fields/bulk 🔒 Organizer Bulk update fields
16 POST /events/{eventId}/fields/{fieldId}/clone 🔒 Organizer Clone a field
Option Management
17 POST /events/{eventId}/fields/{fieldId}/options 🔒 Organizer Add option to a field
18 PUT /events/{eventId}/options/{optionId} 🔒 Organizer Update an option
19 DELETE /events/{eventId}/options/{optionId}?hard=false 🔒 Organizer Delete an option (soft or hard)
20 DELETE /events/{eventId}/fields/{fieldId}/options/bulk?hard=false 🔒 Organizer Bulk delete options
21 PATCH /events/{eventId}/options/bulk 🔒 Organizer Bulk update option labels
Preview
22 GET /events/{eventId}/preview/metadata 🔒 Organizer Get form page metadata
23 GET /events/{eventId}/preview/pages/{pageNumber} 🔒 Organizer Preview a page by number
24 POST /events/{eventId}/preview/pages/{pageNumber}/validate 🔒 Organizer Validate answers without saving
Attendee Submission
25 POST /events/{eventId}/start 🔒 Attendee Start form / get existing draft
26 PUT /events/{eventId}/pages/{pageId}/save 🔒 Attendee Save page answers
27 GET /events/{eventId}/my-response 🔒 Attendee Get my response
28 POST /events/{eventId}/submit 🔒 Attendee Submit form
Organizer — Responses & Analytics
29 GET /events/{eventId}/responses/{responseId} 🔒 Organizer Get response by ID
30 GET /events/{eventId}/responses 🔒 Organizer Get all responses (paginated)
31 GET /events/{eventId}/analytics 🔒 Organizer Get form analytics

All paths are prefixed with /api/v1/e-events/applicant-form.


Data Format Standards

Concern Standard
Timestamps ZonedDateTime — ISO 8601 with offset: 2025-02-17T10:30:45+03:00
Local timestamps LocalDateTime — ISO 8601 no offset: 2025-02-17T10:30:45
Dates YYYY-MM-DD2025-07-18
Times HH:mm18:00
IDs UUID v4 — 3fa85f64-5717-4562-b3fc-2c963f66afa6
Pagination (responses) 0-based page param, Spring Page wrapper
Enums Uppercase: BEFORE_CHECKOUT, SUBMITTED, DROPDOWN, REQUIRED