# 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**: 
- All endpoints require authentication via Bearer token unless specified otherwise
- Form submissions cannot be edited after the status changes from DRAFT to SUBMITTED
- Call owners can only view forms with status SUBMITTED, UNDER_REVIEW, APPROVED, or REJECTED
- Applicants can save forms multiple times while in DRAFT status
- One user can only have one application per call (duplicate prevention)
- Page numbers start from 1 (not 0)
- Default pagination size is 20 items per page
- All timestamps are in ISO 8601 format
- File uploads (documents, certificates) should be handled separately and only URLs are stored in the form

---

## Standard Response Format

All API responses follow a consistent structure using our Globe Response Builder pattern:

### Success Response Structure
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Operation completed successfully",
  "action_time": "2026-02-11T10:30:45",
  "data": {
    // Actual response data goes here
  }
}
```

### Error Response Structure
```json
{
  "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:

- **GET** - <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> - Green (Safe, read-only operations)
- **POST** - <span style="background-color: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">POST</span> - Blue (Create new resources)
- **PUT** - <span style="background-color: #ffc107; color: black; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">PUT</span> - Yellow (Update/replace entire resource)
- **PATCH** - <span style="background-color: #fd7e14; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">PATCH</span> - Orange (Partial updates)
- **DELETE** - <span style="background-color: #dc3545; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">DELETE</span> - Red (Remove resources)

---

## Endpoints

## 1. Start Application Form
**Purpose**: Initialize a new application form for a specific call application in DRAFT status

**Endpoint**: <span style="background-color: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">POST</span> `{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**:
```json
{
  "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):*
```json
{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "User not authenticated",
  "action_time": "2026-02-11T10:30:45",
  "data": "User not authenticated"
}
```

*Forbidden (403):*
```json
{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Not authorized",
  "action_time": "2026-02-11T10:30:45",
  "data": "Not authorized"
}
```

*Not Found (404):*
```json
{
  "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**: <span style="background-color: #ffc107; color: black; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">PUT</span> `{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**:
```json
{
  "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**:
```json
{
  "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):*
```json
{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Form not found",
  "action_time": "2026-02-11T10:35:20",
  "data": "Form not found"
}
```

*Forbidden (403):*
```json
{
  "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**: <span style="background-color: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">POST</span> `{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**:
```json
{
  "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):*
```json
{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Form already submitted",
  "action_time": "2026-02-11T11:00:00",
  "data": "Form already submitted"
}
```

*Not Found (404):*
```json
{
  "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**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{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**:
```json
{
  "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):*
```json
{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Form not found",
  "action_time": "2026-02-11T11:15:00",
  "data": "Form not found"
}
```

*Forbidden (403):*
```json
{
  "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**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{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**:
```json
{
  "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):*
```json
{
  "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**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{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**:
```json
{
  "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**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{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**:
```json
{
  "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**: <span style="background-color: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">POST</span> `{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**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Form reviewed successfully",
  "action_time": "2026-02-11T11:45:00",
  "data": null
}
```

**Error Response Examples**:

*Not Found (404):*
```json
{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Form not found",
  "action_time": "2026-02-11T11:45:00",
  "data": "Form not found"
}
```

*Forbidden (403):*
```json
{
  "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**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{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**:
```json
{
  "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**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{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**:
```json
{
  "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):*
```json
{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Form not found",
  "action_time": "2026-02-11T12:00:00",
  "data": "Form not found"
}
```

*Forbidden (403):*
```json
{
  "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**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{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**:
```json
{
  "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**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{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**:
```json
{
  "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):*
```json
{
  "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**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{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**:
```json
{
  "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**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{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**:
```json
{
  "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):*
```json
{
  "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):*
```json
{
  "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
- **DRAFT**: Form is being filled out, can be edited multiple times
- **SUBMITTED**: Form has been submitted for review, cannot be edited
- **UNDER_REVIEW**: Call owner is actively reviewing the application
- **APPROVED**: Application has been approved
- **REJECTED**: Application has been rejected
- **WITHDRAWN**: Applicant has withdrawn their application

### 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
- Default page size is 20, maximum is 100
- Page numbers start from 1
- Use `totalPages` and `last` to determine if more pages exist
- Consider the response payload size when setting page size

### Common HTTP Status Codes
- `200 OK`: Successful GET/PUT/POST request
- `400 Bad Request`: Invalid request data or form already submitted
- `401 Unauthorized`: Missing or invalid authentication token
- `403 Forbidden`: Insufficient permissions or not authorized
- `404 Not Found`: Resource not found (form, call, or user)
- `500 Internal Server Error`: Unexpected server error

### Data Format Standards
- **Dates**: Use ISO 8601 format (YYYY-MM-DD) for date fields
- **Timestamps**: Use ISO 8601 format with timezone (2026-02-11T10:30:45)
- **UUIDs**: Standard UUID v4 format (550e8400-e29b-41d4-a716-446655440000)
- **Phone Numbers**: Include country code (e.g., +255712345678)
- **URLs**: Must be valid HTTP/HTTPS URLs for document storage

---

## Additional Notes

### Document Upload Strategy
- The API stores URLs to documents, not the documents themselves
- Files should be uploaded to a separate file storage service (e.g., AWS S3, Azure Blob Storage)
- After upload, include the returned URL in the form draft
- Supported document types: Business licenses, tax certificates, ID photos, bank statements, etc.

### Form Validation
- All fields are optional in draft mode to allow progressive completion
- Validation occurs on the client side before submission
- Call owners may define required fields based on call requirements

### Performance Considerations
- Use pagination for large result sets
- Filter by status to reduce payload size
- Consider implementing caching for frequently accessed data
- Use search parameters to narrow down results

### Security Notes
- All endpoints require authentication except where explicitly noted
- Users can only access their own forms unless they are the call owner
- Call owners have read-only access to submitted forms
- Sensitive data (ID numbers, financial info) should be encrypted at rest
- Implement rate limiting to prevent abuse

---

**End of Documentation**

For questions or support, please contact the FursaHub Backend Team.