Calls_service

Calls Service

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

Base URL: https://your-api-domain.com/api/v1

Short Description: The Calls Service API provides a comprehensive platform for managing opportunity calls (job postings, internships, grants, competitions, etc.) with integrated application forms and applicant management. Organizations can create calls, attach custom application forms, and manage the entire application lifecycle from submission to review.

Hints:


User Journey Flow

┌─────────────────────────────────────────────────────────────────────────────┐
│                           CALL CREATOR JOURNEY                               │
└─────────────────────────────────────────────────────────────────────────────┘

1. CREATE CALL (DRAFT)
   │
   ├──> POST /api/v1/calls
   │    └── Status: DRAFT, isActive: false
   │
2. CREATE APPLICATION FORM
   │
   ├──> POST /api/v1/calls/{callId}/form
   │    └── Auto-creates first page
   │
3. BUILD FORM STRUCTURE
   │
   ├──> POST /api/v1/calls/{callId}/form/pages
   │    └── Add additional pages
   │
   ├──> POST /api/v1/calls/{callId}/form/pages/{pageId}/fields
   │    └── Add fields to each page
   │
4. REVIEW & UPDATE CALL
   │
   ├──> GET /api/v1/calls/{callId}
   │    └── Preview call details
   │
   ├──> PUT /api/v1/calls/{callId}
   │    └── Update call information
   │
5. PUBLISH CALL
   │
   ├──> POST /api/v1/calls/{callId}/publish
   │    └── Status: PUBLISHED, isActive: true
   │    └── Applications open
   │
6. MANAGE APPLICATIONS
   │
   ├──> GET /api/v1/calls/{callId}/applications
   │    └── View all applications
   │
   ├──> GET /api/v1/calls/{callId}/applicants
   │    └── Get unique applicants
   │
   ├──> GET /api/v1/calls/{callId}/analytics
   │    └── View form analytics
   │
   ├──> POST /api/v1/calls/applications/{applicationId}/review
   │    └── Accept/Reject applications
   │
7. CLOSE CALL
   │
   └──> POST /api/v1/calls/{callId}/close
        └── Status: CLOSED, isActive: false
        └── No new applications accepted

┌─────────────────────────────────────────────────────────────────────────────┐
│                           APPLICANT JOURNEY                                  │
└─────────────────────────────────────────────────────────────────────────────┘

1. BROWSE CALLS
   │
   ├──> GET /api/v1/calls
   │    └── View active/published calls
   │
2. VIEW CALL DETAILS
   │
   ├──> GET /api/v1/calls/{callId}
   │    └── See full call information
   │
   ├──> GET /api/v1/calls/{callId}/form
   │    └── Preview application form
   │
3. START APPLICATION
   │
   ├──> POST /api/v1/calls/{callId}/apply
   │    └── Creates DRAFT application
   │    └── Returns applicationId & responseId
   │
4. FILL APPLICATION (PAGE BY PAGE)
   │
   ├──> POST /api/v1/calls/applications/{applicationId}/pages/{pageId}
   │    ├── Save draft: moveToNextPage: false
   │    └── Complete page: moveToNextPage: true
   │
   ├──> Repeat for each page
   │
5. SUBMIT APPLICATION
   │
   ├──> POST /api/v1/calls/applications/{applicationId}/submit
   │    └── Status: SUBMITTED
   │    └── Validates all required fields
   │
6. TRACK APPLICATION
   │
   ├──> GET /api/v1/calls/applications/{applicationId}
   │    └── Check application status
   │
   ├──> GET /api/v1/calls/my-applications
   │    └── View all your applications
   │
7. WITHDRAW (OPTIONAL)
   │
   └──> POST /api/v1/calls/applications/{applicationId}/withdraw
        └── Status: WITHDRAWN
        └── Soft delete

┌─────────────────────────────────────────────────────────────────────────────┐
│                        STATUS FLOW DIAGRAM                                   │
└─────────────────────────────────────────────────────────────────────────────┘

CALL STATUSES:
   DRAFT ──[publish]──> PUBLISHED ──[close]──> CLOSED
     │                                             │
     └────────────[delete]────> DELETED <─────────┘

APPLICATION STATUSES:
   DRAFT ──[submit]──> SUBMITTED ──[review]──> UNDER_REVIEW
                           │                         │
                           │                         ├──> ACCEPTED
                           │                         └──> REJECTED
                           │
                      [withdraw]──> WITHDRAWN

┌─────────────────────────────────────────────────────────────────────────────┐
│                    FORM-APPLICATION INTEGRATION                              │
└─────────────────────────────────────────────────────────────────────────────┘

CallsEntity
    └── applicationFormId ──> FormEntity (Form Builder)
                                  └── pages[] ──> FormPageEntity
                                                      └── fields[] ──> FormFieldEntity

CallApplicationEntity
    └── responseId ──> FormResponseEntity (Form Builder)
                           └── answers[] ──> FormAnswerEntity
                                                 └── links to FormFieldEntity

Standard Response Format

All API responses follow a consistent structure using our Globe Response Builder pattern:

Success Response Structure

{
  "success": true,
  "httpStatus": "OK",
  "message": "Operation completed successfully",
  "action_time": "2025-01-30T10:30:45",
  "data": {
    // Actual response data goes here
  }
}

Error Response Structure

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

Standard Response Fields

Field Type Description
success boolean Always true for successful operations, false for errors
httpStatus string HTTP status name (OK, BAD_REQUEST, NOT_FOUND, etc.)
message string Human-readable message describing the operation result
action_time string ISO 8601 timestamp of when the response was generated
data object/string Response payload for success, error details for failures

HTTP Method Badge Standards

For better visual clarity, all endpoints use colored badges for HTTP methods with the following standard colors:


1. Create Call

Purpose: Creates a new call (opportunity/posting). The authenticated user becomes the owner. The call is created in DRAFT status by default.

Endpoint: POST {base_url}

Access Level: 🔒 Protected (Requires Bearer Token · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Request JSON Sample:

{
  "title": "Software Engineer Intern",
  "description": "<p>We are looking for a talented intern...</p>",
  "images": [
    "https://cdn.example.com/banner1.jpg",
    "https://cdn.example.com/banner2.jpg"
  ],
  "applicantsAccepting": 10,
  "applicationStartDate": "2025-10-01T08:00:00",
  "applicationEndDate": "2025-11-01T23:59:59",
  "location": "Dar es Salaam, Tanzania",
  "applicationFormId": null,
  "additionalInfo": {
    "salary": "500 USD/month",
    "duration": "3 months"
  },
  "allowMultipleApplications": false
}

Request Body Parameters:

Parameter Type Required Description Validation
title string Yes Title of the call Max: 255 characters
description string No Rich text (HTML) description of the call Max: 5000 characters
images array<string> No List of image URLs for the call banner/gallery Each item must be a valid URL string
applicantsAccepting integer Yes Maximum number of applicants the call will accept Min: 1
applicationStartDate string (datetime) Yes Start date/time for accepting applications ISO 8601 format
applicationEndDate string (datetime) Yes End date/time for accepting applications ISO 8601 format · Must be after applicationStartDate
location string No Location or address for the call Max: 255 characters
applicationFormId string (UUID) No Link an existing form to this call. Usually set later via the form endpoints Valid UUID or null
additionalInfo object No Flexible key-value map for extra details (salary, duration, etc.) Stored as JSON
allowMultipleApplications boolean No Whether one user can submit more than one application Defaults to false

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Call created successfully",
  "action_time": "2025-10-01T10:30:45",
  "data": {
    "callId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "title": "Software Engineer Intern",
    "description": "<p>We are looking for a talented intern...</p>",
    "images": ["https://cdn.example.com/banner1.jpg"],
    "applicantsAccepting": 10,
    "applicationStartDate": "2025-10-01T08:00:00",
    "applicationEndDate": "2025-11-01T23:59:59",
    "location": "Dar es Salaam, Tanzania",
    "applicationFormId": null,
    "additionalInfo": { "salary": "500 USD/month" },
    "isActive": false,
    "allowMultipleApplications": false,
    "status": "DRAFT",
    "createdBy": "johndoe",
    "createdAt": "2025-10-01T10:30:45",
    "publishedAt": null,
    "closedAt": null,
    "applicationCount": 0
  }
}

Success Response Fields:

Field Description
callId Unique identifier (UUID) of the newly created call
title Title of the call
description Rich text (HTML) description
images List of image URLs
applicantsAccepting Maximum number of applicants allowed
applicationStartDate Application window start timestamp
applicationEndDate Application window end timestamp
location Location string
applicationFormId Linked form UUID (null if no form attached yet)
additionalInfo Custom key-value metadata object
isActive Whether the call is currently active (false on creation)
allowMultipleApplications Whether multiple applications per user are permitted
status Current lifecycle status: DRAFT | PUBLISHED | CLOSED | ARCHIVED | DELETED
createdBy Username of the authenticated creator
createdAt ISO 8601 creation timestamp
publishedAt Timestamp when published (null until published)
closedAt Timestamp when closed (null until closed)
applicationCount Total number of active applications (0 on creation)

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Validation failed",
  "action_time": "2025-10-01T10:30:45",
  "data": {
    "title": "must not be blank",
    "applicantsAccepting": "must not be null"
  }
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone number not verified
422 UNPROCESSABLE_ENTITY Validation failed (e.g. missing title, applicantsAccepting < 1)

2. Get Call

Purpose: Retrieves full details of a single call by its ID. Public — no authentication required.

Endpoint: GET {base_url}/{callId}

Access Level: 🌐 Public (No authentication required)

Authentication: None

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes Unique identifier of the call Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Call retrieved successfully",
  "action_time": "2025-10-01T12:00:00",
  "data": {
    "callId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "title": "Software Engineer Intern",
    "description": "<p>We are looking for a talented intern...</p>",
    "images": ["https://cdn.example.com/banner1.jpg"],
    "applicantsAccepting": 10,
    "applicationStartDate": "2025-10-01T08:00:00",
    "applicationEndDate": "2025-11-01T23:59:59",
    "location": "Dar es Salaam, Tanzania",
    "applicationFormId": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
    "additionalInfo": { "salary": "500 USD/month" },
    "isActive": true,
    "allowMultipleApplications": false,
    "status": "PUBLISHED",
    "createdBy": "johndoe",
    "createdAt": "2025-10-01T10:30:45",
    "publishedAt": "2025-10-02T09:00:00",
    "closedAt": null,
    "applicationCount": 5
  }
}

Success Response Fields:

Field Description
callId Unique identifier (UUID) of the call
title Title of the call
description Rich text (HTML) description
images List of image URLs
applicantsAccepting Maximum number of applicants allowed
applicationStartDate Application window start
applicationEndDate Application window end
location Location string
applicationFormId Linked application form UUID
additionalInfo Custom metadata object
isActive Active flag
allowMultipleApplications Multi-application flag
status DRAFT | PUBLISHED | CLOSED | ARCHIVED | DELETED
createdBy Owner username
createdAt Creation timestamp
publishedAt Published timestamp
closedAt Closed timestamp
applicationCount Total active applications

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Call not found",
  "action_time": "2025-10-01T12:00:00",
  "data": "Call not found"
}
HTTP Status Description
404 NOT_FOUND Call with given ID does not exist or has been soft-deleted

3. Update Call

Purpose: Updates an existing call. Only the call owner (createdBy) can perform this action. All fields are optional — only provided fields are updated (partial update).

Endpoint: PUT {base_url}/{callId}

Access Level: 🔒 Protected (Requires Bearer Token · Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes Unique identifier of the call to update Valid UUID

Request JSON Sample:

{
  "title": "Senior Software Engineer",
  "description": "<p>Updated job description...</p>",
  "images": ["https://cdn.example.com/new-banner.jpg"],
  "applicantsAccepting": 15,
  "applicationStartDate": "2025-10-05T08:00:00",
  "applicationEndDate": "2025-11-15T23:59:59",
  "location": "Arusha, Tanzania",
  "applicationFormId": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
  "additionalInfo": { "salary": "800 USD/month" },
  "isActive": true,
  "allowMultipleApplications": true
}

Request Body Parameters:

Parameter Type Required Description Validation
title string No New title for the call Max: 255 characters
description string No New rich text (HTML) description Max: 5000 characters
images array<string> No Replace the full image list Array of URL strings
applicantsAccepting integer No Update the applicant capacity Min: 1
applicationStartDate string (datetime) No New application start date ISO 8601 format
applicationEndDate string (datetime) No New application end date ISO 8601 format
location string No New location string Max: 255 characters
applicationFormId string (UUID) No Change or set the linked form Valid UUID or null
additionalInfo object No Replace the entire additional info map Stored as JSON
isActive boolean No Manually toggle the active flag true or false
allowMultipleApplications boolean No Toggle multi-application permission true or false

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Call updated successfully",
  "action_time": "2025-10-03T14:00:00",
  "data": {
    "callId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "title": "Senior Software Engineer",
    "description": "<p>Updated job description...</p>",
    "images": ["https://cdn.example.com/new-banner.jpg"],
    "applicantsAccepting": 15,
    "applicationStartDate": "2025-10-05T08:00:00",
    "applicationEndDate": "2025-11-15T23:59:59",
    "location": "Arusha, Tanzania",
    "applicationFormId": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
    "additionalInfo": { "salary": "800 USD/month" },
    "isActive": true,
    "allowMultipleApplications": true,
    "status": "PUBLISHED",
    "createdBy": "johndoe",
    "createdAt": "2025-10-01T10:30:45",
    "publishedAt": "2025-10-02T09:00:00",
    "closedAt": null,
    "applicationCount": 5
  }
}

Success Response Fields:

Field Description
callId UUID of the updated call
title Updated title
description Updated description
images Updated image list
applicantsAccepting Updated capacity
applicationStartDate Updated start date
applicationEndDate Updated end date
location Updated location
applicationFormId Updated linked form UUID
additionalInfo Updated metadata
isActive Updated active flag
allowMultipleApplications Updated multi-application flag
status Current call status (unchanged by update)
createdBy Original owner username
createdAt Original creation timestamp
publishedAt Published timestamp
closedAt Closed timestamp
applicationCount Total active applications

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Access denied: Insufficient permissions",
  "action_time": "2025-10-03T14:00:00",
  "data": "Access denied: Insufficient permissions"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call not found
422 UNPROCESSABLE_ENTITY Validation failed on provided fields

4. Delete Call

Purpose: Soft-deletes a call by setting its status to DELETED and recording the deleted_at timestamp. Only the call owner can delete. The call remains in the database but is excluded from all queries.

Endpoint: DELETE {base_url}/{callId}

Access Level: 🔒 Protected (Requires Bearer Token · Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes Unique identifier of the call to delete Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Call deleted successfully",
  "action_time": "2025-10-05T16:00:00",
  "data": null
}

Success Response Fields:

Field Description
data null — no payload returned on successful deletion

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Call not found",
  "action_time": "2025-10-05T16:00:00",
  "data": "Call not found"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call not found

5. Publish Call

Purpose: Transitions a call from DRAFT to PUBLISHED status, sets isActive to true, and records the publishedAt timestamp. A call must have an application form attached before it can be published.

Endpoint: POST {base_url}/{callId}/publish

Access Level: 🔒 Protected (Requires Bearer Token · Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call to publish Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Call published successfully",
  "action_time": "2025-10-02T09:00:00",
  "data": null
}

Success Response Fields:

Field Description
data null — no payload returned on successful publish

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Cannot publish call without application form",
  "action_time": "2025-10-02T09:00:00",
  "data": "Cannot publish call without application form"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call not found
400 BAD_REQUEST Call is not in DRAFT status or no application form is attached

6. Close Call

Purpose: Manually closes a call — sets status to CLOSED, isActive to false, and records closedAt. After closing, the call no longer accepts new applications. Calls are also auto-closed when their applicationEndDate passes.

Endpoint: POST {base_url}/{callId}/close

Access Level: 🔒 Protected (Requires Bearer Token · Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call to close Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Call closed successfully",
  "action_time": "2025-10-10T18:00:00",
  "data": null
}

Success Response Fields:

Field Description
data null — no payload returned on successful close

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Access denied: Insufficient permissions",
  "action_time": "2025-10-10T18:00:00",
  "data": "Access denied: Insufficient permissions"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call not found

7. List Calls

Purpose: Returns a paginated list of calls. If a status filter is provided, only calls with that status are returned. Otherwise, only active (isActive = true) calls are returned by default. Public endpoint — no authentication required.

Endpoint: GET {base_url}

Access Level: 🌐 Public (No authentication required)

Authentication: None

Query Parameters:

Parameter Type Required Description Validation Default
status string No Filter calls by lifecycle status enum: DRAFT, PUBLISHED, CLOSED, ARCHIVED, DELETED — (returns active calls if omitted)
page integer No Page number (1-based) Min: 1 1
size integer No Number of results per page Min: 1 20

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Calls retrieved successfully",
  "action_time": "2025-10-01T12:00:00",
  "data": {
    "content": [
      {
        "callId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "title": "Software Engineer Intern",
        "shortDescription": "We are looking for a talented intern to join...",
        "bannerImage": "https://cdn.example.com/banner1.jpg",
        "applicantsAccepting": 10,
        "applicationEndDate": "2025-11-01T23:59:59",
        "location": "Dar es Salaam, Tanzania",
        "status": "PUBLISHED",
        "applicationCount": 5,
        "topApplicants": [
          {
            "userId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
            "fullName": "Jane Smith",
            "profileImage": "https://cdn.example.com/avatars/jane.jpg"
          }
        ]
      }
    ],
    "totalElements": 42,
    "totalPages": 3,
    "currentPage": 1,
    "hasMore": true
  }
}

Success Response Fields:

Field Description
data.content Array of CallSummary objects
data.content[].callId UUID of the call
data.content[].title Call title
data.content[].shortDescription First 200 characters of the description (truncated with ... if longer)
data.content[].bannerImage First image URL used as banner (null if no images)
data.content[].applicantsAccepting Maximum applicants capacity
data.content[].applicationEndDate Application deadline
data.content[].location Location string
data.content[].status DRAFT | PUBLISHED | CLOSED | ARCHIVED | DELETED
data.content[].applicationCount Total number of active applications
data.content[].topApplicants Preview of up to 5 most recent applicants
data.content[].topApplicants[].userId Applicant user UUID
data.content[].topApplicants[].fullName Applicant full name
data.content[].topApplicants[].profileImage Applicant profile photo URL
data.totalElements Total number of matching records
data.totalPages Total number of pages
data.currentPage Current page number
data.hasMore true if more pages exist

8. Get My Calls

Purpose: Returns a paginated list of all calls created by the authenticated user, regardless of status. Useful for call owners to manage their own postings.

Endpoint: GET {base_url}/my-calls

Access Level: 🔒 Protected (Requires Bearer Token · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Query Parameters:

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

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Your calls retrieved successfully",
  "action_time": "2025-10-01T12:00:00",
  "data": {
    "content": [
      {
        "callId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "title": "Software Engineer Intern",
        "shortDescription": "We are looking for...",
        "bannerImage": "https://cdn.example.com/banner1.jpg",
        "applicantsAccepting": 10,
        "applicationEndDate": "2025-11-01T23:59:59",
        "location": "Dar es Salaam, Tanzania",
        "status": "DRAFT",
        "applicationCount": 0,
        "topApplicants": []
      }
    ],
    "totalElements": 3,
    "totalPages": 1,
    "currentPage": 1,
    "hasMore": false
  }
}

Success Response Fields:

Field Description
data.content Array of CallSummary objects belonging to the authenticated user
data.content[].callId UUID of the call
data.content[].title Call title
data.content[].shortDescription Truncated description (max 200 chars)
data.content[].bannerImage First image URL or null
data.content[].applicantsAccepting Applicant capacity
data.content[].applicationEndDate Application deadline
data.content[].location Location
data.content[].status Current status
data.content[].applicationCount Application count
data.content[].topApplicants Up to 5 applicant previews
data.totalElements Total records
data.totalPages Total pages
data.currentPage Current page
data.hasMore Pagination flag

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "Token has expired",
  "action_time": "2025-10-01T12:00:00",
  "data": "Token has expired"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone number not verified

9. Get User Published Calls

Purpose: Returns a paginated list of all PUBLISHED calls created by a specific user. Public endpoint — useful for viewing a user's active postings on their profile.

Endpoint: GET {base_url}/users/{userId}/calls

Access Level: 🌐 Public (No authentication required)

Authentication: None

Path Parameters:

Parameter Type Required Description Validation
userId string (UUID) Yes ID of the user whose published calls to retrieve Valid UUID

Query Parameters:

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

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "User calls retrieved successfully",
  "action_time": "2025-10-01T12:00:00",
  "data": {
    "content": [
      {
        "callId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "title": "Software Engineer Intern",
        "shortDescription": "We are looking for...",
        "bannerImage": "https://cdn.example.com/banner1.jpg",
        "applicantsAccepting": 10,
        "applicationEndDate": "2025-11-01T23:59:59",
        "location": "Dar es Salaam, Tanzania",
        "status": "PUBLISHED",
        "applicationCount": 5,
        "topApplicants": []
      }
    ],
    "totalElements": 2,
    "totalPages": 1,
    "currentPage": 1,
    "hasMore": false
  }
}

Success Response Fields:

Field Description
data.content Array of CallSummary objects with status PUBLISHED only
data.content[].callId UUID of the call
data.content[].title Call title
data.content[].shortDescription Truncated description
data.content[].bannerImage First image URL or null
data.content[].applicantsAccepting Applicant capacity
data.content[].applicationEndDate Application deadline
data.content[].location Location
data.content[].status Always PUBLISHED for this endpoint
data.content[].applicationCount Application count
data.content[].topApplicants Up to 5 applicant previews
data.totalElements Total records
data.totalPages Total pages
data.currentPage Current page
data.hasMore Pagination flag

10. Create Form for Call

Purpose: Creates a new application form and automatically links it to the specified call. A first page titled Application Details is auto-created. A call can only have one form — attempting to create another will return an error.

Endpoint: POST {base_url}calls/{callId}/form

Access Level: 🔒 Protected (Requires Bearer Token · Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call to attach the form to Valid UUID

Request JSON Sample:

{
  "title": "Software Engineer Application",
  "description": "Please complete all sections of this application form.",
  "coverPage": {
    "title": "Welcome",
    "message": "Thank you for your interest. This form will take about 10 minutes."
  },
  "isActive": true,
  "allowMultipleSubmissions": false
}

Request Body Parameters:

Parameter Type Required Description Validation
title string No Title of the form Max: 255 characters
description string No Description shown at the top of the form Max: 1000 characters
coverPage object No Optional cover/welcome page settings rendered before form pages Stored as JSON
isActive boolean Yes Whether the form accepts responses Required
allowMultipleSubmissions boolean Yes Whether the same user can submit the form multiple times Required

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Form created successfully",
  "action_time": "2025-10-01T11:00:00",
  "data": {
    "formId": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
    "title": "Software Engineer Application",
    "description": "Please complete all sections...",
    "coverPage": { "title": "Welcome", "message": "..." },
    "isActive": true,
    "allowMultipleSubmissions": false,
    "createdBy": "johndoe",
    "createdAt": "2025-10-01T11:00:00",
    "updatedBy": null,
    "updatedAt": null,
    "pages": [
      {
        "pageId": "p1a2b3c4-d5e6-7890-abcd-ef1234567890",
        "title": "Application Details",
        "description": "Please provide your information",
        "displayOrder": 1,
        "nextButtonText": "Next",
        "fields": []
      }
    ]
  }
}

Success Response Fields:

Field Description
formId UUID of the newly created form
title Form title
description Form description
coverPage Cover page configuration object
isActive Active flag for the form
allowMultipleSubmissions Multi-submission setting
createdBy Owner username
createdAt Creation timestamp
updatedBy Last updater (null initially)
updatedAt Last update timestamp (null initially)
pages Array of page objects. An initial Application Details page is auto-created
pages[].pageId UUID of the page
pages[].title Page title
pages[].description Page description
pages[].displayOrder Order in the form (1-based)
pages[].nextButtonText Label of the Next button (defaults to Next)
pages[].fields Array of field objects on this page (empty initially)

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Call already has a form",
  "action_time": "2025-10-01T11:00:00",
  "data": "Call already has a form"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call not found
400 BAD_REQUEST Call already has a form attached
422 UNPROCESSABLE_ENTITY Validation failed (e.g. missing isActive or allowMultipleSubmissions)

11. Get Call Form

Purpose: Retrieves the application form attached to a call. The call owner can always access the form. Other users can only access it if the call is in PUBLISHED status.

Endpoint: GET {base_url}/calls/{callId}/form

Access Level: 🔒 Protected (Requires Bearer Token · Phone Verified · Owner or Published Call)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call whose form to retrieve Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Form retrieved successfully",
  "action_time": "2025-10-02T10:00:00",
  "data": {
    "formId": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
    "title": "Software Engineer Application",
    "description": "Please complete all sections...",
    "coverPage": { "title": "Welcome" },
    "isActive": true,
    "allowMultipleSubmissions": false,
    "createdBy": "johndoe",
    "createdAt": "2025-10-01T11:00:00",
    "updatedBy": null,
    "updatedAt": null,
    "pages": [
      {
        "pageId": "p1a2b3c4-d5e6-7890-abcd-ef1234567890",
        "title": "Application Details",
        "description": "Please provide your information",
        "displayOrder": 1,
        "nextButtonText": "Next",
        "fields": [
          {
            "fieldId": "fd1a2b3c-d5e6-7890-abcd-ef1234567890",
            "type": "TEXT",
            "label": "Full Name",
            "description": "Enter your legal full name",
            "placeholder": "e.g. Jane Doe",
            "displayOrder": 1,
            "required": true,
            "validation": { "minLength": 2, "maxLength": 100 },
            "options": []
          }
        ]
      }
    ]
  }
}

Success Response Fields:

Field Description
formId Form UUID
title Form title
description Form description
coverPage Cover page config
isActive Active flag
allowMultipleSubmissions Multi-submission flag
createdBy Owner username
createdAt Creation timestamp
updatedBy Last updater
updatedAt Last update timestamp
pages Array of pages with their fields
pages[].pageId Page UUID
pages[].title Page title
pages[].description Page description
pages[].displayOrder Display order
pages[].nextButtonText Next button label
pages[].fields Array of FieldDetail objects
pages[].fields[].fieldId Field UUID
pages[].fields[].type Field type: TEXT | TEXTAREA | EMAIL | PHONE | NUMBER | URL | DATE | TIME | DATETIME | DROPDOWN | RADIO | CHECKBOX | FILE | RATING
pages[].fields[].label Field label
pages[].fields[].description Field description/hint
pages[].fields[].placeholder Placeholder text
pages[].fields[].displayOrder Order within the page
pages[].fields[].required Whether the field is mandatory
pages[].fields[].validation Custom validation rules (minLength, maxLength, min, max, pattern, etc.)
pages[].fields[].options Options for DROPDOWN/RADIO/CHECKBOX fields (empty for other types)

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Call has no form",
  "action_time": "2025-10-02T10:00:00",
  "data": "Call has no form"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or form not accessible (call is not published and user is not owner)
404 NOT_FOUND Call not found
400 BAD_REQUEST Call has no form attached

12. Delete Form for Call

Purpose: Soft-deletes the application form attached to a call and unlinks it from the call (sets applicationFormId to null). Only the call owner can perform this action.

Endpoint: DELETE {base_url}/{callId}/form

Access Level: 🔒 Protected (Requires Bearer Token · Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call whose form to delete Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Form deleted successfully",
  "action_time": "2025-10-03T15:00:00",
  "data": null
}

Success Response Fields:

Field Description
data null — no payload returned on successful deletion

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Call has no form",
  "action_time": "2025-10-03T15:00:00",
  "data": "Call has no form"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call not found
400 BAD_REQUEST Call has no form attached

13. Add Page to Call Form

Purpose: Adds a new page to the call's application form. Pages are appended in order with an auto-incrementing displayOrder. Only the call owner can add pages.

Endpoint: POST {base_url}/{callId}/form/pages

Access Level: 🔒 Protected (Requires Bearer Token · Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call whose form to add a page to Valid UUID

Request JSON Sample:

{
  "title": "Work Experience",
  "description": "Please describe your relevant work experience.",
  "nextButtonText": "Continue"
}

Request Body Parameters:

Parameter Type Required Description Validation
title string No Page title displayed as the page heading Max: 255 characters
description string No Page description shown below the title Max: 1000 characters
nextButtonText string No Custom label for the navigation button Max: 50 characters · Defaults to Next

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Page added successfully",
  "action_time": "2025-10-02T11:00:00",
  "data": {
    "pageId": "p2a3b4c5-d6e7-8901-abcd-ef1234567890",
    "title": "Work Experience",
    "description": "Please describe your relevant work experience.",
    "displayOrder": 2,
    "nextButtonText": "Continue",
    "fields": []
  }
}

Success Response Fields:

Field Description
pageId UUID of the newly created page
title Page title
description Page description
displayOrder Auto-assigned order (incremented from the last page)
nextButtonText Navigation button label
fields Empty array — fields are added separately via the add field endpoint

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Call has no form",
  "action_time": "2025-10-02T11:00:00",
  "data": "Call has no form"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call not found
400 BAD_REQUEST Call has no form attached

14. Update Page in Call Form

Purpose: Updates the title, description, or next button text of an existing page in the call's form. Only the call owner can update pages. All fields are optional.

Endpoint: PUT {base_url}/{callId}/form/pages/{pageId}

Access Level: 🔒 Protected (Requires Bearer Token · Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call Valid UUID
pageId string (UUID) Yes ID of the page to update Valid UUID

Request JSON Sample:

{
  "title": "Professional Experience",
  "description": "Updated: List your last 3 positions.",
  "nextButtonText": "Save & Continue"
}

Request Body Parameters:

Parameter Type Required Description Validation
title string No New page title Max: 255 characters
description string No New page description Max: 1000 characters
nextButtonText string No New navigation button label Max: 50 characters

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Page updated successfully",
  "action_time": "2025-10-03T10:00:00",
  "data": {
    "pageId": "p2a3b4c5-d6e7-8901-abcd-ef1234567890",
    "title": "Professional Experience",
    "description": "Updated: List your last 3 positions.",
    "displayOrder": 2,
    "nextButtonText": "Save & Continue",
    "fields": []
  }
}

Success Response Fields:

Field Description
pageId UUID of the updated page
title Updated title
description Updated description
displayOrder Unchanged display order
nextButtonText Updated button label
fields Array of existing fields on this page

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Page not found",
  "action_time": "2025-10-03T10:00:00",
  "data": "Page not found"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call or page not found

15. Delete Page from Call Form

Purpose: Soft-deletes a page from the call's application form. The page and all its fields are marked as deleted and excluded from subsequent queries.

Endpoint: DELETE {base_url}/{callId}/form/pages/{pageId}

Access Level: 🔒 Protected (Requires Bearer Token · Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call Valid UUID
pageId string (UUID) Yes ID of the page to delete Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Page deleted successfully",
  "action_time": "2025-10-04T09:00:00",
  "data": null
}

Success Response Fields:

Field Description
data null — no payload returned on successful deletion

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Page not found",
  "action_time": "2025-10-04T09:00:00",
  "data": "Page not found"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call or page not found

16. Add Field to Call Form Page

Purpose: Adds a new input field to a specific page of the call's application form. Fields are appended with an auto-incrementing displayOrder. For DROPDOWN, RADIO, and CHECKBOX types, options must be added separately after creating the field.

Endpoint: POST {base_url}/{callId}/form/pages/{pageId}/fields

Access Level: 🔒 Protected (Requires Bearer Token · Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call Valid UUID
pageId string (UUID) Yes ID of the page to add the field to Valid UUID

Request JSON Sample:

{
  "type": "EMAIL",
  "label": "Personal Email",
  "description": "We will use this to send you updates about your application.",
  "placeholder": "you@example.com",
  "required": true,
  "validation": {
    "minLength": 5,
    "maxLength": 100
  }
}

Request Body Parameters:

Parameter Type Required Description Validation
type string Yes The input type of the field enum: TEXT, TEXTAREA, EMAIL, PHONE, NUMBER, URL, DATE, TIME, DATETIME, DROPDOWN, RADIO, CHECKBOX, FILE, RATING
label string Yes Display label for the field Min: 1 · Max: 255 characters
description string No Helper text shown below the field Max: 500 characters
placeholder string No Placeholder text inside the input Max: 255 characters
required boolean No Whether this field must be answered before moving to the next page Defaults to false
validation object No Custom validation rules. Supported keys: minLength, maxLength (strings); min, max (numbers); minSelections, maxSelections (checkboxes); pattern, patternMessage (regex) Stored as JSON

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Field added successfully",
  "action_time": "2025-10-02T11:30:00",
  "data": {
    "fieldId": "fd1a2b3c-d5e6-7890-abcd-ef1234567890",
    "type": "EMAIL",
    "label": "Personal Email",
    "description": "We will use this to send you updates...",
    "placeholder": "you@example.com",
    "displayOrder": 1,
    "required": true,
    "validation": { "minLength": 5, "maxLength": 100 },
    "options": []
  }
}

Success Response Fields:

Field Description
fieldId UUID of the newly created field
type Field input type
label Field label
description Helper text
placeholder Placeholder text
displayOrder Auto-assigned order within the page
required Mandatory flag
validation Custom validation rules object
options Empty array — add options separately for DROPDOWN, RADIO, CHECKBOX fields

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Validation failed",
  "action_time": "2025-10-02T11:30:00",
  "data": {
    "type": "must not be null",
    "label": "must not be blank"
  }
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call or page not found
400 BAD_REQUEST Call has no form attached
422 UNPROCESSABLE_ENTITY Validation failed (e.g. missing type or label)

17. Update Field in Call Form

Purpose: Updates an existing field in the call's application form. All fields are optional — only provided properties are updated.

Endpoint: PUT {base_url}/{callId}/form/fields/{fieldId}

Access Level: 🔒 Protected (Requires Bearer Token · Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call Valid UUID
fieldId string (UUID) Yes ID of the field to update Valid UUID

Request JSON Sample:

{
  "label": "Work Email",
  "description": "Enter your current work email address.",
  "placeholder": "name@company.com",
  "required": false,
  "validation": { "maxLength": 150 }
}

Request Body Parameters:

Parameter Type Required Description Validation
type string No Change the field type enum: TEXT, TEXTAREA, EMAIL, PHONE, NUMBER, URL, DATE, TIME, DATETIME, DROPDOWN, RADIO, CHECKBOX, FILE, RATING
label string No New field label Max: 255 characters
description string No New helper text Max: 500 characters
placeholder string No New placeholder text Max: 255 characters
required boolean No Update the mandatory flag true or false
validation object No Replace the entire validation rules object Stored as JSON

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Field updated successfully",
  "action_time": "2025-10-03T11:00:00",
  "data": {
    "fieldId": "fd1a2b3c-d5e6-7890-abcd-ef1234567890",
    "type": "EMAIL",
    "label": "Work Email",
    "description": "Enter your current work email address.",
    "placeholder": "name@company.com",
    "displayOrder": 1,
    "required": false,
    "validation": { "maxLength": 150 },
    "options": []
  }
}

Success Response Fields:

Field Description
fieldId UUID of the updated field
type Field type (updated or unchanged)
label Updated label
description Updated description
placeholder Updated placeholder
displayOrder Unchanged display order
required Updated mandatory flag
validation Updated validation rules
options Existing options for choice-type fields

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Field not found",
  "action_time": "2025-10-03T11:00:00",
  "data": "Field not found"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call or field not found
400 BAD_REQUEST Call has no form attached

18. Delete Field from Call Form

Purpose: Soft-deletes a field from the call's application form. The field is marked as deleted and excluded from form rendering. Existing answers referencing this field are preserved with fieldDeleted flag set to true.

Endpoint: DELETE {base_url}/{callId}/form/fields/{fieldId}

Access Level: 🔒 Protected (Requires Bearer Token · Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call Valid UUID
fieldId string (UUID) Yes ID of the field to delete Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Field deleted successfully",
  "action_time": "2025-10-04T10:00:00",
  "data": null
}

Success Response Fields:

Field Description
data null — no payload returned on successful deletion

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Field not found",
  "action_time": "2025-10-04T10:00:00",
  "data": "Field not found"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call or field not found

19. Apply to Call

Purpose: Starts a new application for the authenticated user on a published call. Creates a DRAFT application and initializes a form response session. If the call does not allow multiple applications, the user can only have one active application.

Endpoint: POST {base_url}/{callId}/apply

Access Level: 🔒 Protected (Requires Bearer Token · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call to apply to Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Application started successfully",
  "action_time": "2025-10-05T08:00:00",
  "data": {
    "applicationId": "app1a2b3-c4d5-e6f7-8901-234567890abc",
    "callId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "callTitle": "Software Engineer Intern",
    "responseId": "res1a2b3-c4d5-e6f7-8901-234567890abc",
    "status": "DRAFT",
    "appliedAt": "2025-10-05T08:00:00",
    "submittedAt": null,
    "reviewedAt": null,
    "reviewedBy": null,
    "reviewNotes": null,
    "applicant": {
      "userId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "fullName": "Jane Smith",
      "profileImage": "https://cdn.example.com/avatars/jane.jpg"
    }
  }
}

Success Response Fields:

Field Description
applicationId UUID of the newly created application
callId UUID of the call being applied to
callTitle Title of the call
responseId UUID of the form response session — use this in Save Application Page and Submit Application calls
status Initial status: DRAFT
appliedAt Timestamp when application was started
submittedAt null until submitted
reviewedAt null until reviewed by call owner
reviewedBy null until reviewed
reviewNotes null until reviewed
applicant Preview object of the applicant
applicant.userId Applicant's user UUID
applicant.fullName Applicant's full name
applicant.profileImage Applicant's profile photo URL

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "You have already applied",
  "action_time": "2025-10-05T08:00:00",
  "data": "You have already applied"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone number not verified
404 NOT_FOUND Call not found
400 BAD_REQUEST Call is not PUBLISHED, application period has ended, call has no form, or user has already applied (when multiple applications are disabled)

20. Save Application Page

Purpose: Saves the user's answers for a single page of their application form. Can be used for draft-saving (moveToNextPage = false) or for validated progression to the next page (moveToNextPage = true). When moveToNextPage is true, all required fields on the page must be answered and pass validation.

Endpoint: POST {base_url}/applications/{applicationId}/pages/{pageId}

Access Level: 🔒 Protected (Requires Bearer Token · Application Owner · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
applicationId string (UUID) Yes ID of the application Valid UUID
pageId string (UUID) Yes ID of the form page to save answers for Valid UUID

Request JSON Sample:

{
  "pageId": "p1a2b3c4-d5e6-7890-abcd-ef1234567890",
  "answers": {
    "fd1a2b3c-d5e6-7890-abcd-ef1234567890": {
      "value": "Jane Smith",
      "fileUrl": null,
      "fileName": null,
      "fileSize": null,
      "fileType": null
    },
    "fd2b3c4d-e6f7-8901-bcde-f12345678901": {
      "value": "jane@example.com"
    }
  },
  "moveToNextPage": true
}

Request Body Parameters:

Parameter Type Required Description Validation
pageId string (UUID) Yes ID of the page being answered Must match the pageId in the URL
answers object Yes Map of fieldId → AnswerValue. Keys are field UUIDs, values contain the answer See AnswerValue structure below
answers.<fieldId>.value any Yes The answer value. Type depends on field type: string for TEXT/EMAIL/etc, number for NUMBER/RATING, array of option UUIDs for CHECKBOX, single option UUID for DROPDOWN/RADIO Must match the field's expected type
answers.<fieldId>.fileUrl string No URL of an uploaded file (for FILE type fields) Valid URL or null
answers.<fieldId>.fileName string No Original file name null for non-file fields
answers.<fieldId>.fileSize integer No File size in bytes null for non-file fields
answers.<fieldId>.fileType string No MIME type of the file null for non-file fields
moveToNextPage boolean Yes If true, validates required fields and marks the page as complete. If false, saves as draft without validation true or false

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Page saved successfully",
  "action_time": "2025-10-05T08:30:00",
  "data": {
    "responseId": "res1a2b3-c4d5-e6f7-8901-234567890abc",
    "formId": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
    "submittedBy": "janesmith",
    "status": "DRAFT",
    "completedPageIds": ["p1a2b3c4-d5e6-7890-abcd-ef1234567890"],
    "currentPageIndex": 1,
    "startedAt": "2025-10-05T08:00:00",
    "submittedAt": null,
    "completionTimeSeconds": null,
    "answers": [
      {
        "answerId": "ans1a2b3-c4d5-e6f7-8901-234567890abc",
        "fieldId": "fd1a2b3c-d5e6-7890-abcd-ef1234567890",
        "fieldLabel": "Full Name",
        "fieldType": "TEXT",
        "value": "Jane Smith",
        "answeredAt": "2025-10-05T08:30:00",
        "fieldDeleted": false,
        "fileUrl": null,
        "fileName": null,
        "fileSize": null,
        "fileType": null
      }
    ]
  }
}

Success Response Fields:

Field Description
responseId UUID of the form response session
formId UUID of the associated form
submittedBy Username of the applicant
status Response status: DRAFT | SUBMITTED | WITHDRAWN
completedPageIds Set of page UUIDs that have been fully completed
currentPageIndex 0-based index of the current page the user is on
startedAt When the form response was started
submittedAt null until the application is submitted
completionTimeSeconds null until submitted
answers Array of all answers saved so far across all pages
answers[].answerId UUID of the answer record
answers[].fieldId UUID of the field this answer belongs to
answers[].fieldLabel Snapshot of the field label at answer time
answers[].fieldType Snapshot of the field type
answers[].value The saved answer value
answers[].answeredAt Timestamp when the answer was saved
answers[].fieldDeleted true if the field has been deleted since the answer was saved
answers[].fileUrl File URL (for FILE fields)
answers[].fileName File name
answers[].fileSize File size in bytes
answers[].fileType File MIME type

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Validation failed",
  "action_time": "2025-10-05T08:30:00",
  "data": {
    "message": "Validation failed",
    "fieldErrors": [
      {
        "pageId": "p1a2b3c4-d5e6-7890-abcd-ef1234567890",
        "pageTitle": "Application Details",
        "fieldId": "fd1a2b3c-d5e6-7890-abcd-ef1234567890",
        "fieldLabel": "Full Name",
        "errorMessage": "This field is required",
        "errorType": "REQUIRED"
      }
    ]
  }
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the application owner
404 NOT_FOUND Application or page not found
400 BAD_REQUEST Application is not in DRAFT status
422 UNPROCESSABLE_ENTITY Validation failed. Includes detailed field-level errors with pageId, fieldId, fieldLabel, errorMessage, and errorType (REQUIRED | INVALID_TYPE | INVALID_FORMAT | VALIDATION_FAILED)

21. Submit Application

Purpose: Submits a completed application. All pages must be marked as complete before submission is allowed. On success, the application status changes to SUBMITTED and the completion time is recorded.

Endpoint: POST {base_url}/applications/{applicationId}/submit

Access Level: 🔒 Protected (Requires Bearer Token · Application Owner · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
applicationId string (UUID) Yes ID of the application to submit Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Application submitted successfully",
  "action_time": "2025-10-05T09:00:00",
  "data": {
    "applicationId": "app1a2b3-c4d5-e6f7-8901-234567890abc",
    "callId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "callTitle": "Software Engineer Intern",
    "responseId": "res1a2b3-c4d5-e6f7-8901-234567890abc",
    "status": "SUBMITTED",
    "appliedAt": "2025-10-05T08:00:00",
    "submittedAt": "2025-10-05T09:00:00",
    "reviewedAt": null,
    "reviewedBy": null,
    "reviewNotes": null,
    "applicant": {
      "userId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "fullName": "Jane Smith",
      "profileImage": "https://cdn.example.com/avatars/jane.jpg"
    }
  }
}

Success Response Fields:

Field Description
applicationId UUID of the submitted application
callId UUID of the call
callTitle Title of the call
responseId UUID of the form response
status Now SUBMITTED
appliedAt When the application was started
submittedAt Timestamp of successful submission
reviewedAt null until reviewed
reviewedBy null until reviewed
reviewNotes null until reviewed
applicant Applicant preview object

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Cannot submit. Please complete all pages.",
  "action_time": "2025-10-05T09:00:00",
  "data": {
    "message": "Cannot submit. Please complete all pages.",
    "fieldErrors": [
      {
        "pageId": "p2a3b4c5-d6e7-8901-abcd-ef1234567890",
        "pageTitle": "Work Experience",
        "fieldId": "fd3c4d5e-f6a7-8901-bcde-f12345678901",
        "fieldLabel": "Previous Company",
        "errorMessage": "This field is required",
        "errorType": "REQUIRED"
      }
    ]
  }
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the application owner
404 NOT_FOUND Application not found
400 BAD_REQUEST Application is not in DRAFT status
422 UNPROCESSABLE_ENTITY Incomplete pages — includes field-level errors for all required fields on incomplete pages

22. Get Application

Purpose: Retrieves full details of a single application including its current status, timestamps, and review information. Accessible by both the applicant and the call owner.

Endpoint: GET {base_url}/applications/{applicationId}

Access Level: 🔒 Protected (Requires Bearer Token · Application Owner or Call Owner · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
applicationId string (UUID) Yes ID of the application to retrieve Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Application retrieved successfully",
  "action_time": "2025-10-06T10:00:00",
  "data": {
    "applicationId": "app1a2b3-c4d5-e6f7-8901-234567890abc",
    "callId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "callTitle": "Software Engineer Intern",
    "responseId": "res1a2b3-c4d5-e6f7-8901-234567890abc",
    "status": "UNDER_REVIEW",
    "appliedAt": "2025-10-05T08:00:00",
    "submittedAt": "2025-10-05T09:00:00",
    "reviewedAt": "2025-10-06T10:00:00",
    "reviewedBy": "johndoe",
    "reviewNotes": "Strong candidate, moving to interview.",
    "applicant": {
      "userId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "fullName": "Jane Smith",
      "profileImage": "https://cdn.example.com/avatars/jane.jpg"
    }
  }
}

Success Response Fields:

Field Description
applicationId Application UUID
callId Call UUID
callTitle Call title
responseId Form response UUID
status DRAFT | SUBMITTED | UNDER_REVIEW | ACCEPTED | REJECTED | WITHDRAWN
appliedAt Application start timestamp
submittedAt Submission timestamp
reviewedAt Review timestamp
reviewedBy Username of the reviewer (call owner)
reviewNotes Reviewer notes
applicant Applicant preview (userId, fullName, profileImage)

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Access denied: Insufficient permissions",
  "action_time": "2025-10-06T10:00:00",
  "data": "Access denied: Insufficient permissions"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or user is neither the applicant nor the call owner
404 NOT_FOUND Application not found

23. Get Call Applications

Purpose: Returns a paginated list of all applications for a specific call. Only the call owner can access this endpoint — it is used for reviewing and managing incoming applications.

Endpoint: GET {base_url}/{callId}/applications

Access Level: 🔒 Protected (Requires Bearer Token · Call Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call to list applications for Valid UUID

Query Parameters:

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

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Applications retrieved successfully",
  "action_time": "2025-10-06T11:00:00",
  "data": {
    "content": [
      {
        "applicationId": "app1a2b3-c4d5-e6f7-8901-234567890abc",
        "callId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "callTitle": "Software Engineer Intern",
        "callBannerImage": "https://cdn.example.com/banner1.jpg",
        "status": "SUBMITTED",
        "appliedAt": "2025-10-05T08:00:00",
        "submittedAt": "2025-10-05T09:00:00",
        "applicant": {
          "userId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
          "fullName": "Jane Smith",
          "profileImage": "https://cdn.example.com/avatars/jane.jpg"
        }
      }
    ],
    "totalElements": 12,
    "totalPages": 1,
    "currentPage": 1,
    "hasMore": false
  }
}

Success Response Fields:

Field Description
data.content Array of ApplicationSummary objects
data.content[].applicationId Application UUID
data.content[].callId Call UUID
data.content[].callTitle Call title
data.content[].callBannerImage First image of the call used as banner (or null)
data.content[].status DRAFT | SUBMITTED | UNDER_REVIEW | ACCEPTED | REJECTED | WITHDRAWN
data.content[].appliedAt Application start timestamp
data.content[].submittedAt Submission timestamp (null if still draft)
data.content[].applicant Applicant preview (userId, fullName, profileImage)
data.totalElements Total matching records
data.totalPages Total pages
data.currentPage Current page
data.hasMore Pagination flag

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Access denied: Insufficient permissions",
  "action_time": "2025-10-06T11:00:00",
  "data": "Access denied: Insufficient permissions"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call not found

24. Get My Applications

Purpose: Returns a paginated list of all applications submitted by the authenticated user across all calls. Useful for applicants to track the status of their submissions.

Endpoint: GET {base_url}/my-applications

Access Level: 🔒 Protected (Requires Bearer Token · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Query Parameters:

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

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Your applications retrieved successfully",
  "action_time": "2025-10-06T12:00:00",
  "data": {
    "content": [
      {
        "applicationId": "app1a2b3-c4d5-e6f7-8901-234567890abc",
        "callId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "callTitle": "Software Engineer Intern",
        "callBannerImage": "https://cdn.example.com/banner1.jpg",
        "status": "ACCEPTED",
        "appliedAt": "2025-10-05T08:00:00",
        "submittedAt": "2025-10-05T09:00:00",
        "applicant": {
          "userId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
          "fullName": "Jane Smith",
          "profileImage": "https://cdn.example.com/avatars/jane.jpg"
        }
      }
    ],
    "totalElements": 4,
    "totalPages": 1,
    "currentPage": 1,
    "hasMore": false
  }
}

Success Response Fields:

Field Description
data.content Array of ApplicationSummary objects for the authenticated user
data.content[].applicationId Application UUID
data.content[].callId Call UUID
data.content[].callTitle Call title
data.content[].callBannerImage Call banner image URL
data.content[].status Current application status
data.content[].appliedAt Start timestamp
data.content[].submittedAt Submission timestamp
data.content[].applicant Applicant preview
data.totalElements Total records
data.totalPages Total pages
data.currentPage Current page
data.hasMore Pagination flag

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "Token has expired",
  "action_time": "2025-10-06T12:00:00",
  "data": "Token has expired"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone number not verified

25. Get Call Applicants

Purpose: Returns a list of all unique applicants (user previews) for a given call. Only the call owner can access this. Useful for quickly viewing who has applied without full application details.

Endpoint: GET {base_url}/{callId}/applicants

Access Level: 🔒 Protected (Requires Bearer Token · Call Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call to get applicants for Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Applicants retrieved successfully",
  "action_time": "2025-10-06T13:00:00",
  "data": [
    {
      "userId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "fullName": "Jane Smith",
      "profileImage": "https://cdn.example.com/avatars/jane.jpg"
    },
    {
      "userId": "c3d4e5f6-a7b8-9012-cdef-123456789012",
      "fullName": "John Doe",
      "profileImage": "https://cdn.example.com/avatars/john.jpg"
    }
  ]
}

Success Response Fields:

Field Description
data Array of ApplicantPreview objects
data[].userId UUID of the applicant
data[].fullName Applicant's full name
data[].profileImage Applicant's profile photo URL

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Access denied: Insufficient permissions",
  "action_time": "2025-10-06T13:00:00",
  "data": "Access denied: Insufficient permissions"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call not found

26. Review Application

Purpose: Allows the call owner to review an application by updating its status (e.g., UNDER_REVIEW, ACCEPTED, REJECTED) and optionally adding review notes. Only the call owner can perform reviews.

Endpoint: POST {base_url}/applications/{applicationId}/review

Access Level: 🔒 Protected (Requires Bearer Token · Call Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
applicationId string (UUID) Yes ID of the application to review Valid UUID

Query Parameters:

Parameter Type Required Description Validation Default
status string Yes The new status to set on the application enum: DRAFT, SUBMITTED, UNDER_REVIEW, ACCEPTED, REJECTED, WITHDRAWN
notes string No Optional review notes or feedback for the applicant Any string

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Application reviewed successfully",
  "action_time": "2025-10-07T14:00:00",
  "data": null
}

Success Response Fields:

Field Description
data null — no payload returned on successful review

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Application not found",
  "action_time": "2025-10-07T14:00:00",
  "data": "Application not found"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Application not found

27. Withdraw Application

Purpose: Allows an applicant to withdraw their own application. Sets the status to WITHDRAWN and soft-deletes the application record. This action cannot be undone.

Endpoint: POST {base_url}/applications/{applicationId}/withdraw

Access Level: 🔒 Protected (Requires Bearer Token · Application Owner · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
applicationId string (UUID) Yes ID of the application to withdraw Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Application withdrawn successfully",
  "action_time": "2025-10-08T15:00:00",
  "data": null
}

Success Response Fields:

Field Description
data null — no payload returned on successful withdrawal

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Access denied: Insufficient permissions",
  "action_time": "2025-10-08T15:00:00",
  "data": "Access denied: Insufficient permissions"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the application owner
404 NOT_FOUND Application not found

28. Get Call Form Analytics

Purpose: Returns aggregated analytics for the application form of a call — including total responses, status breakdown, and average completion time. Only the call owner can access analytics.

Endpoint: GET {base_url}/{callId}/analytics

Access Level: 🔒 Protected (Requires Bearer Token · Call Owner Only · Phone Verified)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token: Bearer <token>

Path Parameters:

Parameter Type Required Description Validation
callId string (UUID) Yes ID of the call to get analytics for Valid UUID

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Analytics retrieved successfully",
  "action_time": "2025-10-08T16:00:00",
  "data": {
    "totalResponses": 42,
    "submittedCount": 35,
    "draftCount": 5,
    "averageCompletionTimeSeconds": 487,
    "statusBreakdown": {
      "SUBMITTED": 35,
      "DRAFT": 5,
      "WITHDRAWN": 2
    }
  }
}

Success Response Fields:

Field Description
totalResponses Total number of form responses (all statuses)
submittedCount Number of fully submitted responses
draftCount Number of responses still in DRAFT
averageCompletionTimeSeconds Average time (in seconds) from form start to submission, across all submitted responses
statusBreakdown Object mapping each response status to its count
statusBreakdown.SUBMITTED Count of submitted responses
statusBreakdown.DRAFT Count of draft responses
statusBreakdown.WITHDRAWN Count of withdrawn responses

Error Response JSON Sample:

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Call has no form",
  "action_time": "2025-10-08T16:00:00",
  "data": "Call has no form"
}
HTTP Status Description
401 UNAUTHORIZED Token missing, invalid, or expired
403 FORBIDDEN Phone not verified or not the call owner
404 NOT_FOUND Call not found
400 BAD_REQUEST Call has no form attached

Useless Call Form API

Author:{}

Last Updated: 2026-02-11
Version: v1.0

Base URL: https://api.fursahub.com/api/v1

Short Description: The Useless Call Form API manages application forms for calls/opportunities posted on the FursaHub platform. It handles the complete lifecycle of application forms from creation through submission to review and approval/rejection. This API enables users to apply to calls by filling out detailed application forms and allows call owners to manage and review submitted applications.

Hints:


Standard Response Format

All API responses follow a consistent structure using our Globe Response Builder pattern:

Success Response Structure

{
  "success": true,
  "httpStatus": "OK",
  "message": "Operation completed successfully",
  "action_time": "2026-02-11T10:30:45",
  "data": {
    // Actual response data goes here
  }
}

Error Response Structure

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

Standard Response Fields

Field Type Description
success boolean Always true for successful operations, false for errors
httpStatus string HTTP status name (OK, BAD_REQUEST, NOT_FOUND, etc.)
message string Human-readable message describing the operation result
action_time string ISO 8601 timestamp of when the response was generated
data object/string Response payload for success, error details for failures

HTTP Method Badge Standards

For better visual clarity, all endpoints use colored badges for HTTP methods with the following standard colors:


Endpoints

1. Start Application Form

Purpose: Initialize a new application form for a specific call application in DRAFT status

Endpoint: POST {base_url}/useless-forms/applications/{applicationId}/start

Access Level: 🔒 Protected (Requires Bearer Token - Must be the application owner)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
applicationId UUID Yes Unique identifier of the call application Must be valid UUID format

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Form started successfully",
  "action_time": "2026-02-11T10:30:45",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "applicationId": "660e8400-e29b-41d4-a716-446655440001",
    "callId": "770e8400-e29b-41d4-a716-446655440002",
    "userId": "880e8400-e29b-41d4-a716-446655440003",
    "applicationStatus": "DRAFT",
    "createdAt": "2026-02-11T10:30:45",
    "updatedAt": "2026-02-11T10:30:45"
  }
}

Success Response Fields:

Field Description
id Unique identifier of the form
applicationId Reference to the call application
callId Reference to the call this form belongs to
userId ID of the user who created the form
applicationStatus Current status of the form (always DRAFT when starting)
createdAt Timestamp when the form was created
updatedAt Timestamp when the form was last updated

Error Response Examples:

Unauthorized (401):

{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "User not authenticated",
  "action_time": "2026-02-11T10:30:45",
  "data": "User not authenticated"
}

Forbidden (403):

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Not authorized",
  "action_time": "2026-02-11T10:30:45",
  "data": "Not authorized"
}

Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Application not found",
  "action_time": "2026-02-11T10:30:45",
  "data": "Application not found"
}

2. Save Form Draft

Purpose: Save or update form data while keeping it in DRAFT status (can be called multiple times)

Endpoint: PUT {base_url}/useless-forms/applications/{applicationId}/draft

Access Level: 🔒 Protected (Requires Bearer Token - Must be the form owner)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
applicationId UUID Yes Unique identifier of the call application Must be valid UUID format

Request JSON Sample:

{
  "whoIsApplying": "MYSELF",
  "fullName": "John Doe",
  "username": "johndoe",
  "email": "john.doe@example.com",
  "phoneNumber": "+255712345678",
  "countryCode": "+255",
  "nationality": "Tanzanian",
  "preferredContactMethod": "EMAIL",
  "profilePictureUrl": "https://storage.example.com/profiles/john.jpg",
  "employmentStatus": "EMPLOYED",
  "employerName": "Tech Solutions Ltd",
  "jobTitle": "Software Engineer",
  "employmentType": "FULL_TIME",
  "dateOfBirth": "1990-05-15",
  "placeOfBirth": "Dar es Salaam",
  "sex": "MALE",
  "maritalStatus": "SINGLE",
  "ethnicity": "African",
  "idType": "NIDA",
  "idNumber": "19900515-12345-67890-12",
  "nameOnId": "John Doe",
  "idPhotoUrl": "https://storage.example.com/ids/john_id.jpg",
  "primaryAddress": "123 Main Street",
  "city": "Dar es Salaam",
  "country": "Tanzania",
  "region": "Dar es Salaam",
  "district": "Kinondoni",
  "zipCode": "12345",
  "ownsBusiness": true,
  "hasBusinessLicense": true,
  "businessName": "JD Tech Solutions",
  "businessEmail": "info@jdtech.com",
  "businessPhoneNumber": "+255712345679",
  "businessTinNumber": "123-456-789",
  "businessIndustry": "TECHNOLOGY",
  "businessWebsite": "https://jdtech.com",
  "businessAddress": "456 Business Avenue",
  "businessLicenseCertificateUrl": "https://storage.example.com/licenses/business_license.pdf",
  "businessTinCertificateUrl": "https://storage.example.com/certificates/tin.pdf",
  "loanApplicationLetterUrl": "https://storage.example.com/letters/loan_application.pdf",
  "boardResolutionUrl": "https://storage.example.com/resolutions/board_resolution.pdf",
  "businessLicenseEvidenceUrl": "https://storage.example.com/evidence/license_evidence.pdf",
  "taxClearanceCertificateUrl": "https://storage.example.com/certificates/tax_clearance.pdf",
  "taxpayerTin": "987-654-321",
  "taxpayerIdType": "NIDA",
  "taxpayerIdNumber": "19900515-12345-67890-12",
  "taxpayerNameOnId": "John Doe",
  "certificateOfRegistrationUrl": "https://storage.example.com/certificates/registration.pdf",
  "bankStatementUrl": "https://storage.example.com/statements/bank_statement.pdf",
  "allPurposeSupportingDocsUrl": "https://storage.example.com/docs/supporting_docs.pdf",
  "brelaSearchReturnsUrl": "https://storage.example.com/brela/search_returns.pdf",
  "callNotes": "Applying for business expansion loan"
}

Request Body Parameters:

Parameter Type Required Description Validation
whoIsApplying string No Who is submitting the application enum: MYSELF, SOMEONE_ELSE
fullName string No Full legal name of the applicant Max: 200 characters
username string No Username of the applicant Max: 100 characters
email string No Email address Must be valid email format
phoneNumber string No Phone number with country code Max: 20 characters
countryCode string No International dialing code Max: 10 characters
nationality string No Nationality of the applicant Max: 100 characters
preferredContactMethod string No Preferred way to be contacted enum: EMAIL, SMS, PHONE_CALL
profilePictureUrl string No URL to profile picture Valid URL format
employmentStatus string No Current employment situation enum: EMPLOYED, SELF_EMPLOYED, UNEMPLOYED, STUDENT, RETIRED
employerName string No Name of current employer Max: 200 characters
jobTitle string No Current job title Max: 200 characters
employmentType string No Type of employment enum: FULL_TIME, PART_TIME, CONTRACT, FREELANCE, INTERNSHIP
dateOfBirth date No Date of birth ISO 8601 date format (YYYY-MM-DD)
placeOfBirth string No Place where applicant was born Max: 200 characters
sex string No Biological sex enum: MALE, FEMALE, OTHER, PREFER_NOT_TO_SAY
maritalStatus string No Current marital status enum: SINGLE, MARRIED, DIVORCED, WIDOWED, SEPARATED
ethnicity string No Ethnic background Max: 100 characters
idType string No Type of identification document enum: NATIONAL_ID, PASSPORT, DRIVERS_LICENSE, VOTERS_ID, NIDA
idNumber string No Identification document number Max: 100 characters
nameOnId string No Name as it appears on ID Max: 200 characters
idPhotoUrl string No URL to ID document photo Valid URL format
primaryAddress string No Primary residential address Max: 500 characters
city string No City of residence Max: 100 characters
country string No Country of residence Max: 100 characters
region string No Region/State of residence Max: 100 characters
district string No District of residence Max: 100 characters
zipCode string No Postal/ZIP code Max: 20 characters
ownsBusiness boolean No Whether applicant owns a business true or false
hasBusinessLicense boolean No Whether business has a valid license true or false
businessName string No Registered business name Max: 200 characters
businessEmail string No Business email address Must be valid email format
businessPhoneNumber string No Business contact number Max: 20 characters
businessTinNumber string No Business Tax Identification Number Max: 100 characters
businessIndustry string No Industry/sector of business enum: AGRICULTURE, MANUFACTURING, RETAIL, TECHNOLOGY, HEALTHCARE, EDUCATION, FINANCE, CONSTRUCTION, HOSPITALITY, TRANSPORTATION, REAL_ESTATE, PROFESSIONAL_SERVICES, ENTERTAINMENT, MARKETING, OTHER
businessWebsite string No Business website URL Valid URL format
businessAddress string No Physical business address Max: 500 characters
businessLicenseCertificateUrl string No URL to business license document Valid URL format
businessTinCertificateUrl string No URL to TIN certificate Valid URL format
loanApplicationLetterUrl string No URL to loan application letter Valid URL format
boardResolutionUrl string No URL to board resolution document Valid URL format
businessLicenseEvidenceUrl string No URL to business license evidence Valid URL format
taxClearanceCertificateUrl string No URL to tax clearance certificate Valid URL format
taxpayerTin string No Personal Tax Identification Number Max: 100 characters
taxpayerIdType string No Type of taxpayer ID enum: NATIONAL_ID, PASSPORT, DRIVERS_LICENSE, VOTERS_ID, NIDA
taxpayerIdNumber string No Taxpayer ID number Max: 100 characters
taxpayerNameOnId string No Name as appears on taxpayer ID Max: 200 characters
certificateOfRegistrationUrl string No URL to certificate of registration Valid URL format
bankStatementUrl string No URL to bank statement Valid URL format
allPurposeSupportingDocsUrl string No URL to general supporting documents Valid URL format
brelaSearchReturnsUrl string No URL to BRELA search returns Valid URL format
llcFundApplicationLetterUrl string No URL to LLC fund application letter Valid URL format
llcMemartUrl string No URL to LLC MEMART document Valid URL format
llcCertificateOfIncorporationUrl string No URL to LLC certificate of incorporation Valid URL format
partnershipDeedUrl string No URL to partnership deed Valid URL format
partnershipCertificateRegistrationUrl string No URL to partnership certificate Valid URL format
partnershipMemartUrl string No URL to partnership MEMART Valid URL format
partnershipCertificateIncorporationUrl string No URL to partnership incorporation cert Valid URL format
generalBrelaSearchUrl string No URL to general BRELA search Valid URL format
generalFundApplicationUrl string No URL to general fund application Valid URL format
generalMemartUrl string No URL to general MEMART Valid URL format
generalCertificateIncorporationUrl string No URL to general certificate of incorporation Valid URL format
callNotes string No Additional notes about the application Max: 5000 characters

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Draft saved successfully",
  "action_time": "2026-02-11T10:35:20",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "applicationId": "660e8400-e29b-41d4-a716-446655440001",
    "callId": "770e8400-e29b-41d4-a716-446655440002",
    "userId": "880e8400-e29b-41d4-a716-446655440003",
    "whoIsApplying": "MYSELF",
    "fullName": "John Doe",
    "email": "john.doe@example.com",
    "phoneNumber": "+255712345678",
    "applicationStatus": "DRAFT",
    "createdAt": "2026-02-11T10:30:45",
    "updatedAt": "2026-02-11T10:35:20"
  }
}

Error Response Examples:

Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Form not found",
  "action_time": "2026-02-11T10:35:20",
  "data": "Form not found"
}

Forbidden (403):

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Not authorized",
  "action_time": "2026-02-11T10:35:20",
  "data": "Not authorized"
}

3. Submit Application Form

Purpose: Submit a draft form for review (changes status from DRAFT to SUBMITTED)

Endpoint: POST {base_url}/useless-forms/applications/{applicationId}/submit

Access Level: 🔒 Protected (Requires Bearer Token - Must be the form owner)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication
Content-Type string Yes application/json

Path Parameters:

Parameter Type Required Description Validation
applicationId UUID Yes Unique identifier of the call application Must be valid UUID format

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Form submitted successfully",
  "action_time": "2026-02-11T11:00:00",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "applicationId": "660e8400-e29b-41d4-a716-446655440001",
    "callId": "770e8400-e29b-41d4-a716-446655440002",
    "userId": "880e8400-e29b-41d4-a716-446655440003",
    "fullName": "John Doe",
    "email": "john.doe@example.com",
    "applicationStatus": "SUBMITTED",
    "submittedAt": "2026-02-11T11:00:00",
    "createdAt": "2026-02-11T10:30:45",
    "updatedAt": "2026-02-11T11:00:00"
  }
}

Success Response Fields:

Field Description
submittedAt Timestamp when the form was submitted
applicationStatus Changed to SUBMITTED status

Error Response Examples:

Bad Request (400):

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Form already submitted",
  "action_time": "2026-02-11T11:00:00",
  "data": "Form already submitted"
}

Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Form not found",
  "action_time": "2026-02-11T11:00:00",
  "data": "Form not found"
}

4. Get Form by Application ID

Purpose: Retrieve a specific form using the application ID

Endpoint: GET {base_url}/useless-forms/applications/{applicationId}

Access Level: 🔒 Protected (Requires Bearer Token - Must be form owner or call owner)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description Validation
applicationId UUID Yes Unique identifier of the call application Must be valid UUID format

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Form retrieved successfully",
  "action_time": "2026-02-11T11:15:00",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "applicationId": "660e8400-e29b-41d4-a716-446655440001",
    "callId": "770e8400-e29b-41d4-a716-446655440002",
    "userId": "880e8400-e29b-41d4-a716-446655440003",
    "whoIsApplying": "MYSELF",
    "fullName": "John Doe",
    "username": "johndoe",
    "email": "john.doe@example.com",
    "phoneNumber": "+255712345678",
    "countryCode": "+255",
    "nationality": "Tanzanian",
    "preferredContactMethod": "EMAIL",
    "profilePictureUrl": "https://storage.example.com/profiles/john.jpg",
    "employmentStatus": "EMPLOYED",
    "employerName": "Tech Solutions Ltd",
    "jobTitle": "Software Engineer",
    "employmentType": "FULL_TIME",
    "dateOfBirth": "1990-05-15",
    "placeOfBirth": "Dar es Salaam",
    "sex": "MALE",
    "maritalStatus": "SINGLE",
    "ethnicity": "African",
    "idType": "NIDA",
    "idNumber": "19900515-12345-67890-12",
    "nameOnId": "John Doe",
    "idPhotoUrl": "https://storage.example.com/ids/john_id.jpg",
    "primaryAddress": "123 Main Street",
    "city": "Dar es Salaam",
    "country": "Tanzania",
    "region": "Dar es Salaam",
    "district": "Kinondoni",
    "zipCode": "12345",
    "ownsBusiness": true,
    "hasBusinessLicense": true,
    "businessName": "JD Tech Solutions",
    "businessEmail": "info@jdtech.com",
    "businessPhoneNumber": "+255712345679",
    "businessTinNumber": "123-456-789",
    "businessIndustry": "TECHNOLOGY",
    "businessWebsite": "https://jdtech.com",
    "businessAddress": "456 Business Avenue",
    "applicationStatus": "SUBMITTED",
    "submittedAt": "2026-02-11T11:00:00",
    "createdAt": "2026-02-11T10:30:45",
    "updatedAt": "2026-02-11T11:00:00"
  }
}

Error Response Examples:

Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Form not found",
  "action_time": "2026-02-11T11:15:00",
  "data": "Form not found"
}

Forbidden (403):

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Not authorized",
  "action_time": "2026-02-11T11:15:00",
  "data": "Not authorized"
}

5. Get Form by Form ID

Purpose: Retrieve a specific form using the form's unique ID

Endpoint: GET {base_url}/useless-forms/{formId}

Access Level: 🔒 Protected (Requires Bearer Token - Must be form owner or call owner)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description Validation
formId UUID Yes Unique identifier of the form Must be valid UUID format

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Form retrieved successfully",
  "action_time": "2026-02-11T11:20:00",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "applicationId": "660e8400-e29b-41d4-a716-446655440001",
    "callId": "770e8400-e29b-41d4-a716-446655440002",
    "userId": "880e8400-e29b-41d4-a716-446655440003",
    "fullName": "John Doe",
    "email": "john.doe@example.com",
    "applicationStatus": "SUBMITTED",
    "submittedAt": "2026-02-11T11:00:00",
    "createdAt": "2026-02-11T10:30:45",
    "updatedAt": "2026-02-11T11:00:00"
  }
}

Error Response Examples:

Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Form not found",
  "action_time": "2026-02-11T11:20:00",
  "data": "Form not found"
}

6. Get All Forms for a Call

Purpose: Retrieve all application forms submitted for a specific call with optional status filtering

Endpoint: GET {base_url}/useless-forms/calls/{callId}/forms

Access Level: 🔒 Protected (Requires Bearer Token - Must be call owner)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description Validation
callId UUID Yes Unique identifier of the call Must be valid UUID format

Query Parameters:

Parameter Type Required Description Validation Default
status string No Filter forms by application status enum: DRAFT, SUBMITTED, UNDER_REVIEW, APPROVED, REJECTED, WITHDRAWN null (all statuses)
page integer No Page number for pagination Min: 1 1
size integer No Number of items per page Min: 1, Max: 100 20

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Forms retrieved successfully",
  "action_time": "2026-02-11T11:25:00",
  "data": {
    "content": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "applicationId": "660e8400-e29b-41d4-a716-446655440001",
        "callId": "770e8400-e29b-41d4-a716-446655440002",
        "callTitle": "SME Business Loan 2026",
        "fullName": "John Doe",
        "email": "john.doe@example.com",
        "applicationStatus": "SUBMITTED",
        "submittedAt": "2026-02-11T11:00:00",
        "createdAt": "2026-02-11T10:30:45"
      },
      {
        "id": "550e8400-e29b-41d4-a716-446655440004",
        "applicationId": "660e8400-e29b-41d4-a716-446655440005",
        "callId": "770e8400-e29b-41d4-a716-446655440002",
        "callTitle": "SME Business Loan 2026",
        "fullName": "Jane Smith",
        "email": "jane.smith@example.com",
        "applicationStatus": "APPROVED",
        "submittedAt": "2026-02-10T14:30:00",
        "createdAt": "2026-02-10T09:15:00"
      }
    ],
    "pageable": {
      "pageNumber": 0,
      "pageSize": 20,
      "sort": {
        "empty": true,
        "sorted": false,
        "unsorted": true
      },
      "offset": 0,
      "paged": true,
      "unpaged": false
    },
    "totalElements": 2,
    "totalPages": 1,
    "last": true,
    "size": 20,
    "number": 0,
    "sort": {
      "empty": true,
      "sorted": false,
      "unsorted": true
    },
    "numberOfElements": 2,
    "first": true,
    "empty": false
  }
}

Success Response Fields:

Field Description
content Array of form summaries
content[].id Unique identifier of the form
content[].applicationId Reference to the call application
content[].callId Reference to the call
content[].callTitle Title of the call
content[].fullName Applicant's full name
content[].email Applicant's email
content[].applicationStatus Current status of the application
content[].submittedAt When the form was submitted
content[].createdAt When the form was created
totalElements Total number of forms across all pages
totalPages Total number of pages
size Number of items per page
number Current page number (0-indexed)
first Whether this is the first page
last Whether this is the last page

7. Get My Forms

Purpose: Retrieve all forms created by the authenticated user

Endpoint: GET {base_url}/useless-forms/my-forms

Access Level: 🔒 Protected (Requires Bearer Token)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Query Parameters:

Parameter Type Required Description Validation Default
page integer No Page number for pagination Min: 1 1
size integer No Number of items per page Min: 1, Max: 100 20

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Your forms retrieved successfully",
  "action_time": "2026-02-11T11:30:00",
  "data": {
    "content": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "applicationId": "660e8400-e29b-41d4-a716-446655440001",
        "callId": "770e8400-e29b-41d4-a716-446655440002",
        "callTitle": "SME Business Loan 2026",
        "fullName": "John Doe",
        "email": "john.doe@example.com",
        "applicationStatus": "SUBMITTED",
        "submittedAt": "2026-02-11T11:00:00",
        "createdAt": "2026-02-11T10:30:45"
      },
      {
        "id": "550e8400-e29b-41d4-a716-446655440006",
        "applicationId": "660e8400-e29b-41d4-a716-446655440007",
        "callId": "770e8400-e29b-41d4-a716-446655440008",
        "callTitle": "Youth Startup Grant 2026",
        "fullName": "John Doe",
        "email": "john.doe@example.com",
        "applicationStatus": "DRAFT",
        "submittedAt": null,
        "createdAt": "2026-02-09T08:20:00"
      }
    ],
    "totalElements": 2,
    "totalPages": 1,
    "size": 20,
    "number": 0,
    "first": true,
    "last": true,
    "empty": false
  }
}

8. Review Application Form

Purpose: Review and update the status of a submitted form (approve, reject, etc.)

Endpoint: POST {base_url}/useless-forms/{formId}/review

Access Level: 🔒 Protected (Requires Bearer Token - Must be call owner)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description Validation
formId UUID Yes Unique identifier of the form to review Must be valid UUID format

Query Parameters:

Parameter Type Required Description Validation Default
status string Yes New status for the application enum: SUBMITTED, UNDER_REVIEW, APPROVED, REJECTED, WITHDRAWN null
notes string No Review notes or feedback for the applicant Max: 5000 characters null

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Form reviewed successfully",
  "action_time": "2026-02-11T11:45:00",
  "data": null
}

Error Response Examples:

Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Form not found",
  "action_time": "2026-02-11T11:45:00",
  "data": "Form not found"
}

Forbidden (403):

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Not authorized",
  "action_time": "2026-02-11T11:45:00",
  "data": "Not authorized"
}

9. Get Form Statistics for Call

Purpose: Get aggregated statistics of forms by status for a specific call

Endpoint: GET {base_url}/useless-forms/calls/{callId}/stats

Access Level: 🔒 Protected (Requires Bearer Token - Must be call owner)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description Validation
callId UUID Yes Unique identifier of the call Must be valid UUID format

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Stats retrieved successfully",
  "action_time": "2026-02-11T11:50:00",
  "data": {
    "submitted": 45,
    "approved": 12,
    "rejected": 8,
    "draft": 23,
    "total": 88
  }
}

Success Response Fields:

Field Description
submitted Number of forms in SUBMITTED status
approved Number of forms in APPROVED status
rejected Number of forms in REJECTED status
draft Number of forms in DRAFT status
total Total number of all forms for this call

10. Get User's Form for Specific Call

Purpose: Retrieve a specific user's form for a particular call

Endpoint: GET {base_url}/useless-forms/calls/{callId}/users/{userId}

Access Level: 🔒 Protected (Requires Bearer Token - Must be the user themselves or call owner)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description Validation
callId UUID Yes Unique identifier of the call Must be valid UUID format
userId UUID Yes Unique identifier of the user Must be valid UUID format

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Form retrieved successfully",
  "action_time": "2026-02-11T12:00:00",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "applicationId": "660e8400-e29b-41d4-a716-446655440001",
    "callId": "770e8400-e29b-41d4-a716-446655440002",
    "userId": "880e8400-e29b-41d4-a716-446655440003",
    "fullName": "John Doe",
    "email": "john.doe@example.com",
    "applicationStatus": "APPROVED",
    "submittedAt": "2026-02-11T11:00:00",
    "createdAt": "2026-02-11T10:30:45",
    "updatedAt": "2026-02-11T11:45:00"
  }
}

Error Response Examples:

Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Form not found",
  "action_time": "2026-02-11T12:00:00",
  "data": "Form not found"
}

Forbidden (403):

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Cannot view form at this stage",
  "action_time": "2026-02-11T12:00:00",
  "data": "Cannot view form at this stage"
}

11. Get Total Applicants Count

Purpose: Get the total number of applicants for a specific call

Endpoint: GET {base_url}/useless-forms/calls/{callId}/applicants/count

Access Level: 🔒 Protected (Requires Bearer Token)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description Validation
callId UUID Yes Unique identifier of the call Must be valid UUID format

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Applicant count retrieved successfully",
  "action_time": "2026-02-11T12:05:00",
  "data": {
    "totalApplicants": 88
  }
}

Success Response Fields:

Field Description
totalApplicants Total number of unique applicants for this call

12. Get My Status in Call

Purpose: Get the authenticated user's application status for a specific call

Endpoint: GET {base_url}/useless-forms/calls/{callId}/my-status

Access Level: 🔒 Protected (Requires Bearer Token)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description Validation
callId UUID Yes Unique identifier of the call Must be valid UUID format

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Your status retrieved successfully",
  "action_time": "2026-02-11T12:10:00",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "applicationId": "660e8400-e29b-41d4-a716-446655440001",
    "callId": "770e8400-e29b-41d4-a716-446655440002",
    "userId": "880e8400-e29b-41d4-a716-446655440003",
    "fullName": "John Doe",
    "email": "john.doe@example.com",
    "applicationStatus": "UNDER_REVIEW",
    "submittedAt": "2026-02-11T11:00:00",
    "createdAt": "2026-02-11T10:30:45",
    "updatedAt": "2026-02-11T11:45:00"
  }
}

Error Response Examples:

Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "You have not applied to this call",
  "action_time": "2026-02-11T12:10:00",
  "data": "You have not applied to this call"
}

13. Check If User Has Applied

Purpose: Check whether the authenticated user has already applied to a specific call

Endpoint: GET {base_url}/useless-forms/calls/{callId}/check-applied

Access Level: 🔒 Protected (Requires Bearer Token)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description Validation
callId UUID Yes Unique identifier of the call Must be valid UUID format

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Check completed",
  "action_time": "2026-02-11T12:15:00",
  "data": {
    "hasApplied": true
  }
}

Success Response Fields:

Field Description
hasApplied Boolean indicating whether the user has applied (true) or not (false)

14. Get Applicants for Call (With Filters)

Purpose: Retrieve a paginated list of applicants for a specific call with optional filtering by status and search term

Endpoint: GET {base_url}/useless-forms/calls/{callId}/applicants

Access Level: 🔒 Protected (Requires Bearer Token - Must be call owner)

Authentication: Bearer Token

Request Headers:

Header Type Required Description
Authorization string Yes Bearer token for authentication

Path Parameters:

Parameter Type Required Description Validation
callId UUID Yes Unique identifier of the call Must be valid UUID format

Query Parameters:

Parameter Type Required Description Validation Default
status string No Filter applicants by application status enum: DRAFT, SUBMITTED, UNDER_REVIEW, APPROVED, REJECTED, WITHDRAWN null (all statuses)
search string No Search term to filter by name, email, or phone number Max: 200 characters null
page integer No Page number for pagination Min: 1 1
size integer No Number of items per page Min: 1, Max: 100 20

Success Response JSON Sample:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Applicants retrieved successfully",
  "action_time": "2026-02-11T12:20:00",
  "data": {
    "content": [
      {
        "userId": "880e8400-e29b-41d4-a716-446655440003",
        "fullName": "John Doe",
        "email": "john.doe@example.com",
        "phoneNumber": "+255712345678",
        "applicationStatus": "SUBMITTED",
        "submittedAt": "2026-02-11T11:00:00",
        "createdAt": "2026-02-11T10:30:45"
      },
      {
        "userId": "880e8400-e29b-41d4-a716-446655440009",
        "fullName": "Jane Smith",
        "email": "jane.smith@example.com",
        "phoneNumber": "+255723456789",
        "applicationStatus": "APPROVED",
        "submittedAt": "2026-02-10T14:30:00",
        "createdAt": "2026-02-10T09:15:00"
      }
    ],
    "totalElements": 45,
    "totalPages": 3,
    "size": 20,
    "number": 0,
    "first": true,
    "last": false,
    "empty": false
  }
}

Success Response Fields:

Field Description
content Array of applicant summaries
content[].userId Unique identifier of the user/applicant
content[].fullName Applicant's full name
content[].email Applicant's email address
content[].phoneNumber Applicant's phone number
content[].applicationStatus Current status of the application
content[].submittedAt When the application was submitted
content[].createdAt When the application was created
totalElements Total number of applicants across all pages
totalPages Total number of pages
size Number of items per page
number Current page number (0-indexed)
first Whether this is the first page
last Whether this is the last page

Error Response Examples:

Forbidden (403):

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Not authorized to view applicants for this call",
  "action_time": "2026-02-11T12:20:00",
  "data": "Not authorized to view applicants for this call"
}

Not Found (404):

{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Call not found",
  "action_time": "2026-02-11T12:20:00",
  "data": "Call not found"
}

Quick Reference Guide

Application Status Flow

DRAFT → SUBMITTED → UNDER_REVIEW → APPROVED/REJECTED
                                  ↘ WITHDRAWN (optional)

Status Descriptions

Authorization Rules

Role Can Start Form Can Save Draft Can Submit Can Review Can View All Forms
Applicant (Form Owner)
Call Owner
Other Users

Common Use Cases

Use Case 1: User Applies to a Call

  1. POST /applications/{applicationId}/start - Start form
  2. PUT /applications/{applicationId}/draft - Save progress (can repeat)
  3. POST /applications/{applicationId}/submit - Submit form

Use Case 2: User Checks Their Application Status

  1. GET /calls/{callId}/check-applied - Check if already applied
  2. GET /calls/{callId}/my-status - View current status

Use Case 3: Call Owner Reviews Applications

  1. GET /calls/{callId}/applicants?status=SUBMITTED - Get submitted applications
  2. GET /calls/{callId}/users/{userId} - View specific application
  3. POST /{formId}/review?status=APPROVED&notes=Great candidate - Approve/Reject

Use Case 4: Call Owner Views Statistics

  1. GET /calls/{callId}/stats - View aggregated statistics
  2. GET /calls/{callId}/applicants/count - Get total applicant count

Pagination Best Practices

Common HTTP Status Codes

Data Format Standards


Additional Notes

Document Upload Strategy

Form Validation

Performance Considerations

Security Notes


End of Documentation

For questions or support, please contact the FursaHub Backend Team.