{ "openapi": "3.0.0", "info": { "title": "Migrant Mobile API", "description": "Comprehensive API endpoints for the Migrant Mobile Application, covering worker registration, password login, token authentication, profile management, and interactive job offer responses.", "version": "1.0.0" }, "servers": [ { "url": "/api", "description": "Local development API prefix" } ], "security": [ { "bearerAuth": [] } ], "paths": { "/sponsors/register": { "post": { "tags": [ "Sponsor/Auth" ], "summary": "Register Sponsor Account", "description": "Registers a new sponsor with basic information and uploads their organization/trade license. Sponsors have restricted access \u2014 dashboard and charity events only. No payment required.", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "full_name", "mobile", "password", "organization_name", "email", "nationality", "city", "address", "country_code" ], "properties": { "full_name": { "type": "string", "example": "Mohammed Al-Rashidi", "description": "Full legal name of the sponsor. (REQUIRED)" }, "mobile": { "type": "string", "example": "+971501112233", "description": "Mobile phone number \u00e2\u20ac\u201d must be unique. (REQUIRED)" }, "password": { "type": "string", "format": "password", "example": "securepass123", "description": "Login password (min 6 characters). (REQUIRED)" }, "license": { "type": "object", "description": "Optional JSON object containing extracted organization/trade license details.", "properties": { "document_type": { "type": "string", "example": "dubai_commercial_license" }, "country": { "type": "string", "example": "United Arab Emirates" }, "authority": { "type": "string", "example": "Dubai Economy and Tourism" }, "license_no": { "type": "string", "example": "1426961" }, "company_name": { "type": "string", "example": "NEST CLIMATE TECHNICAL SERVICES L.L.C" }, "business_name": { "type": "string", "example": "NEST CLIMATE TECHNICAL SERVICES L.L.C" }, "license_category": { "type": "string", "example": "Dep. of Economic Development" }, "legal_type": { "type": "string", "example": "Limited Liability Company(LLC)" }, "issue_date": { "type": "string", "example": "22/10/2024" }, "expiry_date": { "type": "string", "example": "21/10/2026" }, "main_license_no": { "type": "string", "example": "1426961" }, "register_no": { "type": "string", "example": "2436760" }, "dcci_no": { "type": "string", "example": "570232" }, "members": { "type": "array", "items": { "type": "object", "properties": { "person_no": { "type": "string", "example": "1709285" }, "name": { "type": "string", "example": "SEYED ABDUL RAHMAN SHERIF NISAR" }, "nationality": { "type": "string", "example": "India" }, "role": { "type": "string", "example": "Manager" } } } } } }, "emirates_id": { "type": "object", "description": "Optional JSON object containing extracted Emirates ID details.", "properties": { "emirates_id_number": { "type": "string", "example": "784-1988-5310327-2" }, "name": { "type": "string", "example": "KRISHNA PRASAD" }, "nationality": { "type": "string", "example": "NPL" }, "gender": { "type": "string", "example": "Male" }, "date_of_birth": { "type": "string", "example": "1988-03-22" }, "expiry_date": { "type": "string", "example": "2028-04-11" }, "issue_date": { "type": "string", "example": "2023-04-11" }, "employer": { "type": "string", "example": "Federal Authority" }, "issue_place": { "type": "string", "example": "Abu Dhabi" }, "occupation": { "type": "string", "example": "Manager" }, "card_number": { "type": "string", "example": "151023946" } } }, "organization_name": { "type": "string", "example": "Al-Rashidi Charitable Foundation", "description": "Name of the sponsoring organization. (REQUIRED)" }, "email": { "type": "string", "format": "email", "example": "info@alrashidi.ae", "description": "Email address (must be unique). (REQUIRED)" }, "nationality": { "type": "string", "example": "UAE", "description": "Nationality of the sponsor. (REQUIRED)" }, "city": { "type": "string", "example": "Dubai", "description": "City of residence. (REQUIRED)" }, "address": { "type": "string", "example": "Villa 12, Jumeirah 2", "description": "Physical address. (REQUIRED)" }, "country_code": { "type": "string", "example": "+971", "description": "Country dial code. (REQUIRED)" }, "license_expiry": { "type": "string", "format": "date", "example": "2028-06-12", "description": "Expiry date of the license (YYYY-MM-DD). (REQUIRED)" }, "fcm_token": { "type": "string", "example": "fcm_token_example", "description": "Firebase Cloud Messaging token for push notifications." } } } } } }, "responses": { "201": { "description": "Sponsor registered successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Sponsor account registered successfully. Your license is pending admin review." }, "data": { "type": "object", "properties": { "sponsor": { "$ref": "#/components/schemas/Sponsor" }, "token": { "type": "string", "example": "abc123...bearerToken..." } } } } } } } }, "422": { "description": "Validation error (duplicate mobile/email, missing required fields)." } } } }, "/sponsors/register/license": { "post": { "tags": [ "Sponsor/Auth" ], "summary": "Upload Sponsor Trade License", "description": "Uploads and processes the trade license document of a Sponsor using OCR.", "security": [], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "required": [ "email", "license_file" ], "properties": { "email": { "type": "string", "format": "email", "example": "info@alrashidi.ae", "description": "Email address of the registered sponsor. (REQUIRED)" }, "license_file": { "type": "string", "format": "binary", "description": "Trade license image/PDF file. (REQUIRED)" } } } } } }, "responses": { "200": { "description": "Trade license processed successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "License uploaded and processed successfully." }, "ocr_extracted_data": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "expiry_date": { "type": "string", "example": "2028-06-12" }, "license_number": { "type": "string", "example": "123456" }, "organization_name": { "type": "string", "example": "Charity Co" } } }, "email": { "type": "string", "example": "info@alrashidi.ae" } } } } } }, "404": { "description": "Sponsor account not found." }, "422": { "description": "Validation error." } } } }, "/sponsors/login": { "post": { "tags": [ "Sponsor/Auth" ], "summary": "Authenticate Sponsor or Employer", "description": "Unified authentication endpoint. Validates email/mobile and password, then returns a stateless Bearer token and the user's role (employer or sponsor). Same behavior as /employers/login.", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "password" ], "properties": { "email": { "type": "string", "example": "ahmad@example.com", "description": "Email address (required if mobile is not provided)" }, "mobile": { "type": "string", "example": "+971509990001", "description": "Mobile number (required if email is not provided)" }, "password": { "type": "string", "example": "Password@123" }, "fcm_token": { "type": "string", "example": "fcm_token_example", "description": "Firebase Cloud Messaging token for push notifications." } } } } } }, "responses": { "200": { "description": "Login successful. Returns Bearer token and role.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Login successful." }, "role": { "type": "string", "example": "sponsor", "enum": [ "employer", "sponsor" ] }, "data": { "type": "object", "properties": { "token": { "type": "string", "example": "api_token_here" } } } } } } } } } } }, "/sponsors/dashboard": { "get": { "tags": [ "Sponsor" ], "summary": "Sponsor Dashboard", "description": "Returns the sponsor profile summary, latest charity events, and total & active counts for employers and workers.", "responses": { "200": { "description": "Dashboard data retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean" }, "data": { "type": "object", "properties": { "sponsor": { "type": "object" }, "recent_charity_events": { "type": "array", "items": { "type": "object" } }, "total_events": { "type": "integer" }, "employer_stats": { "type": "object", "properties": { "total": { "type": "integer", "example": 12 }, "active": { "type": "integer", "example": 8 } } }, "worker_stats": { "type": "object", "properties": { "total": { "type": "integer", "example": 150 }, "active": { "type": "integer", "example": 120 } } } } } } } } } }, "401": { "description": "Unauthenticated." } } } }, "/sponsors/charity-events": { "get": { "tags": [ "Sponsor" ], "summary": "List Charity Events", "description": "Returns a paginated list of all charity and announcement events. Optionally filter by type.", "parameters": [ { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 15 } }, { "name": "type", "in": "query", "schema": { "type": "string" }, "description": "Optional event type filter (e.g. 'charity', 'update')." } ], "responses": { "200": { "description": "Events retrieved successfully." }, "401": { "description": "Unauthenticated." } } }, "post": { "tags": [ "Sponsor" ], "summary": "Post Charity Event (Sponsor)", "description": "Creates and publishes a new charity event or community drive for the authenticated sponsor.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "title", "body", "event_date", "start_time", "end_time", "provided_items", "location_details", "location_pin" ], "properties": { "title": { "type": "string", "example": "Free Dental Checkup Drive" }, "body": { "type": "string", "example": "Emirates Charity is organizing a free dental checkup for all workers this Friday morning." }, "type": { "type": "string", "enum": [ "charity", "info", "warning", "success" ], "example": "charity" }, "event_date": { "type": "string", "format": "date", "example": "2026-06-15" }, "start_time": { "type": "string", "example": "09:00 AM" }, "end_time": { "type": "string", "example": "04:00 PM" }, "provided_items": { "type": "string", "example": "Free Dental screening, cleanings, and wellness kits" }, "location_details": { "type": "string", "example": "Al Quoz Community Hall, Dubai" }, "location_pin": { "type": "string", "format": "uri", "example": "https://maps.app.goo.gl/xyz" } } } } } }, "responses": { "201": { "description": "Charity event posted successfully." }, "401": { "description": "Unauthenticated." }, "422": { "description": "Validation error." } } } }, "/sponsors/profile": { "get": { "tags": [ "Sponsor" ], "summary": "Get Sponsor Profile", "description": "Returns the full profile of the authenticated sponsor.", "responses": { "200": { "description": "Profile retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "sponsor": { "$ref": "#/components/schemas/Sponsor" } } } } } } } }, "401": { "description": "Unauthenticated." } } } }, "/sponsors/profile/update": { "post": { "tags": [ "Sponsor" ], "summary": "Update Sponsor Profile Details", "description": "Updates the authenticated sponsor's profile details including optional Emirates ID metadata. Password changes are not supported via this endpoint.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "email", "mobile", "organization_name", "city", "address", "nationality", "country_code" ], "properties": { "name": { "type": "string", "example": "Ahmad Bin Ahmed", "description": "Sponsor's full name (required if full_name is not provided)" }, "full_name": { "type": "string", "example": "Ahmad Bin Ahmed", "description": "Sponsor's full name (required if name is not provided)" }, "email": { "type": "string", "format": "email", "example": "test.sponsor@example.com" }, "mobile": { "type": "string", "example": "+971509990001" }, "organization_name": { "type": "string", "example": "Charity Co" }, "city": { "type": "string", "example": "Abu Dhabi" }, "address": { "type": "string", "example": "Villa 45, Street 12" }, "nationality": { "type": "string", "example": "Emirati" }, "country_code": { "type": "string", "example": "+971" }, "fcm_token": { "type": "string", "example": "fcm_token_example", "description": "Firebase Cloud Messaging token for push notifications." }, "license": { "type": "object", "description": "Optional JSON object containing extracted commercial license details.", "properties": { "license_number": { "type": "string", "example": "828302" }, "organization_name": { "type": "string", "example": "MSJ INTERNATIONAL TECHNICAL SERVICES L.L.C" }, "expiry_date": { "type": "string", "example": "05/03/2026" }, "document_type": { "type": "string", "example": "dubai_commercial_license" }, "country": { "type": "string", "example": "United Arab Emirates" }, "authority": { "type": "string", "example": "Dubai Economy and Tourism" }, "license_no": { "type": "string", "example": "828302" }, "company_name": { "type": "string", "example": "MSJ INTERNATIONAL TECHNICAL SERVICES L.L.C" }, "business_name": { "type": "string", "example": "MSJ INTERNATIONAL TECHNICAL SERVICES L.L.C" }, "license_category": { "type": "string", "example": "Dep. of Economic Development" }, "legal_type": { "type": "string", "example": "Limited Liability Company Single Owner(LLC- - SO)" }, "issue_date": { "type": "string", "example": "06/03/2019" }, "main_license_no": { "type": "string", "example": "828302" }, "register_no": { "type": "string", "example": "1656486" }, "dcci_no": { "type": "string", "example": "317412" }, "members": { "type": "array", "items": { "type": "object", "properties": { "person_no": { "type": "string", "example": "752967" }, "name": { "type": "string", "example": "Lo lo wallus issued in" }, "nationality": { "type": "string", "example": "India" }, "role": { "type": "string", "example": "Shares Owner Who" } } } } } }, "emirates_id": { "type": "object", "description": "Optional JSON object containing extracted Emirates ID details.", "properties": { "emirates_id_number": { "type": "string", "example": "784-1988-5310327-2" }, "name": { "type": "string", "example": "KRISHNA PRASAD" }, "nationality": { "type": "string", "example": "NPL" }, "date_of_birth": { "type": "string", "example": "1988-03-22" }, "expiry_date": { "type": "string", "example": "2028-04-11" }, "issue_date": { "type": "string", "example": "2023-04-11" }, "employer": { "type": "string", "example": "Federal Authority" }, "issue_place": { "type": "string", "example": "Abu Dhabi" }, "occupation": { "type": "string", "example": "Manager" }, "card_number": { "type": "string", "example": "151023946" }, "gender": { "type": "string", "example": "M" } } } } } } } }, "responses": { "200": { "description": "Profile updated successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Profile updated successfully." }, "data": { "type": "object", "properties": { "sponsor": { "$ref": "#/components/schemas/Sponsor" } } } } } } } }, "401": { "description": "Unauthenticated." }, "422": { "description": "Validation error (duplicate mobile/email, mismatched immutable fields, or name extraction failure)." } } } }, "/workers/register": { "post": { "tags": [ "Worker/Auth" ], "summary": "Register Worker Account (Step 1)", "description": "Creates the worker account and returns a secure Bearer token.\n\nDocument upload is a **separate step** after registration:\n- `POST /workers/register/passport` \u2014 upload passport (OCR-processed)\n- `POST /workers/register/visa` \u2014 upload visa (OCR-processed)\n\nBoth document endpoints require the Bearer token returned here.", "security": [], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "required": [ "name", "phone", "salary", "password" ], "properties": { "name": { "type": "string", "example": "Amina Al-Masry", "description": "Full legal name of the worker. (REQUIRED)" }, "phone": { "type": "string", "example": "+971509998888", "description": "Contact mobile phone number (must be unique). (REQUIRED)" }, "salary": { "type": "number", "format": "float", "example": 1500, "description": "Desired minimum monthly salary in AED. (REQUIRED)" }, "password": { "type": "string", "format": "password", "example": "securepassword123", "description": "Secret password for subsequent mobile logins (min 6 chars). (REQUIRED)" }, "skills": { "type": "array", "items": { "type": "integer" }, "example": [ 1, 3 ], "description": "Optional array of Skill IDs (can be sent as comma-separated string e.g. '1,3' or json '[1,3]' in multipart)." }, "language": { "type": "string", "example": "English, Arabic", "description": "Languages spoken by the worker (e.g. 'English, Arabic, Hindi')." }, "nationality": { "type": "string", "example": "Egypt", "description": "Nationality of the worker." }, "age": { "type": "integer", "example": 28, "description": "Age of the worker." }, "experience": { "type": "string", "example": "4 Years", "description": "Years of experience." }, "in_country": { "type": "boolean", "example": true, "description": "Whether the worker is currently in-country (true) or out-country (false)." }, "visa_status": { "type": "string", "example": "Tourist Visa", "description": "Visa status (only required/applicable if in_country is true)." }, "preferred_job_type": { "type": "string", "example": "full-time", "description": "Preferred job type." }, "main_profession": { "type": "string", "example": "Housemaid", "description": "Main profession of the worker selected from the master dropdown.", "enum": [ "Housemaid", "Nanny", "Cook", "Driver", "Caregiver" ] }, "live_in_out": { "type": "string", "enum": [ "live_in", "live_out" ], "example": "live_out", "description": "Accommodation preference (live_in, live_out)." }, "gender": { "type": "string", "enum": [ "male", "female", "other" ], "example": "male", "description": "Gender of the worker (male, female, other)." }, "preferred_location": { "type": "string", "example": "Dubai Marina", "description": "Preferred work location/area." }, "fcm_token": { "type": "string", "example": "fcm_token_example", "description": "Firebase Cloud Messaging token for push notifications." }, "passport": { "type": "object", "description": "Optional JSON object containing extracted passport details.", "properties": { "authority": { "type": "string" }, "date_of_birth": { "type": "string", "example": "14/05/1990" }, "date_of_expiry": { "type": "string", "example": "05/07/2022" }, "date_of_issue": { "type": "string", "example": "05/07/2017" }, "document_type": { "type": "string" }, "given_names": { "type": "string" }, "issuing_country": { "type": "string" }, "nationality": { "type": "string" }, "ocr_accuracy": { "type": "number", "format": "float", "example": 99 }, "passport_number": { "type": "string" }, "personal_number": { "type": "string" }, "place_of_birth": { "type": "string" }, "sex": { "type": "string" }, "surname": { "type": "string" } } }, "visa": { "type": "object", "description": "Standardized UAE Visa metadata.", "properties": { "document_type": { "type": "string", "example": "uae_visa" }, "country": { "type": "string", "example": "United Arab Emirates" }, "visa_type": { "type": "string", "example": "ENTRY PERMIT" }, "entry_permit_no": { "type": "string", "example": "77003098 / 2019 / 204" }, "issue_date": { "type": "string", "example": "2022-02-16" }, "valid_until": { "type": "string", "example": "2024-02-15" }, "uid_no": { "type": "string", "example": "207404887" }, "full_name": { "type": "string", "example": "Mr.MUHAMMAD NADEEM RASHEED" }, "nationality": { "type": "string", "example": "PAKISTAN" }, "place_of_birth": { "type": "string", "example": "SIALKOT PAK" }, "date_of_birth": { "type": "string", "example": "25-JUN-1999" }, "passport_no": { "type": "string", "example": "EN9458281" }, "profession": { "type": "string", "example": "SALES REPRESENTATIVE" }, "sponsor_name": { "type": "string", "example": "Sponsor Name" }, "ocr_accuracy": { "type": "number", "format": "float", "example": 97.4 }, "sponsor": { "type": "object", "properties": { "name": { "type": "string", "example": "Sponsor Name" }, "address": { "type": "string", "example": "Dubai Marina, Dubai" }, "phone": { "type": "string", "example": "2977725" } } } } } } } } } }, "responses": { "201": { "description": "Worker registered successfully. Use the returned token for document upload steps.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Worker registered successfully. Please upload your passport and visa documents." }, "data": { "type": "object", "properties": { "worker": { "$ref": "#/components/schemas/Worker" }, "token": { "type": "string", "example": "abc123xyz456...secureToken..." } } } } } } } }, "422": { "description": "Validation error \u2014 field validation failed or Passport OCR extraction failed.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "Validation error." }, "errors": { "type": "object", "properties": { "phone": { "type": "array", "items": { "type": "string" }, "example": [ "This mobile number is already registered." ] }, "name": { "type": "array", "items": { "type": "string" }, "example": [ "The name field is required." ] } } } } } } } }, "500": { "description": "Server error during registration (e.g. database transaction failure).", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "An error occurred during worker registration. Please try again." }, "error": { "type": "string", "example": "Internal Server Error" } } } } } } } } }, "/workers/login": { "post": { "tags": [ "Worker/Auth" ], "summary": "Authenticate Worker", "description": "Validates worker credentials (mobile phone number and password) and generates a secure, stateless Bearer token for api access.", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "phone", "password" ], "properties": { "phone": { "type": "string", "example": "+971509998888", "description": "Registered mobile phone number." }, "password": { "type": "string", "format": "password", "example": "securepassword123", "description": "Secret account password." }, "fcm_token": { "type": "string", "example": "fcm_token_example", "description": "Firebase Cloud Messaging token for push notifications." } } } } } }, "responses": { "200": { "description": "Worker logged in successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Worker logged in successfully." }, "data": { "type": "object", "properties": { "worker": { "$ref": "#/components/schemas/Worker" }, "token": { "type": "string", "example": "abc123xyz456...secureToken..." } } } } } } } }, "401": { "description": "Unauthorized access.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "Invalid mobile number or password." } } } } } } } } }, "/workers/ocr/passport-vision": { "post": { "tags": [ "Worker/Auth" ], "summary": "Extract Passport Data using Google Cloud Vision API", "description": "Upload a passport image file to extract OCR data using the Google Cloud Vision API.", "security": [], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "required": [ "passport_file" ], "properties": { "passport_file": { "type": "string", "format": "binary", "description": "Passport image file (jpg/png/jpeg, max 10MB)." } } } } } }, "responses": { "200": { "description": "Passport data successfully extracted.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "passport_number": { "type": "string", "example": "Z43R34255" }, "given_names": { "type": "string", "example": "AHMAD" }, "date_of_birth": { "type": "string", "example": "03/07/1978" }, "nationality": { "type": "string", "example": "ARE" }, "issuing_country": { "type": "string", "example": "ARE" }, "place_of_birth": { "type": "string", "example": "DUBAI" }, "date_of_issue": { "type": "string", "example": "10/02/2015" }, "date_of_expiry": { "type": "string", "example": "10/02/2020" } } } } } } } }, "422": { "description": "Validation error (missing passport_file)." }, "400": { "description": "OCR processing error or failed Google Vision API request." } } } }, "/workers/config": { "get": { "tags": [ "Worker/Auth" ], "summary": "Get Supported Languages and Config", "description": "Returns a list of supported regional languages (Hindi, Swahili, Tagalog, Tamil) for helper onboarding.", "security": [], "responses": { "200": { "description": "Config and supported languages retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "languages": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string", "example": "HI" }, "name": { "type": "string", "example": "Hindi (\u0939\u093f\u0928\u094d\u0926\u0940)" } } } } } } } } } } } }, "/workers/skills": { "get": { "tags": [ "Worker/Auth" ], "summary": "Get Master Skills List", "description": "Returns a list of all available master skills for helper onboarding profile setup.", "security": [], "responses": { "200": { "description": "Master skills list retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "skills": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "example": 1 }, "name": { "type": "string", "example": "Cooking" } } } } } } } } } } } }, "/nationalities": { "get": { "tags": [ "General" ], "summary": "Get Nationalities List", "description": "Returns a list of supported nationalities translated to the requested language. Supports en, hindi (hi), sawahi (sw), taglo (tl), tamil (ta).", "security": [], "parameters": [ { "name": "lang", "in": "query", "schema": { "type": "string", "default": "en" }, "description": "Language locale code (e.g. 'en', 'hindi', 'sawahi', 'taglo', 'tamil')" }, { "name": "Accept-Language", "in": "header", "schema": { "type": "string" }, "description": "Fallback header locale (e.g. 'en', 'hi', 'sw', 'tl', 'ta')" }, { "name": "search", "in": "query", "schema": { "type": "string" }, "description": "Search keyword to filter nationalities by name or code" }, { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 }, "description": "Page number for pagination" }, { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 500 }, "description": "Number of nationalities to return per page. Defaults to 500 on the backend to retrieve all nationalities by default." } ], "responses": { "200": { "description": "Nationalities list retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "nationalities": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string", "example": "IN" }, "name": { "type": "string", "example": "Indian" } } } }, "pagination": { "type": "object", "properties": { "total": { "type": "integer", "example": 185 }, "per_page": { "type": "integer", "example": 15 }, "current_page": { "type": "integer", "example": 1 }, "last_page": { "type": "integer", "example": 13 } } } } } } } } } } } } }, "/languages": { "get": { "tags": [ "General" ], "summary": "Get Languages List", "description": "Returns a list of supported languages translated to the requested language. Supports en, hindi (hi), sawahi (sw), taglo (tl), tamil (ta).", "security": [], "parameters": [ { "name": "lang", "in": "query", "schema": { "type": "string", "default": "en" }, "description": "Language locale code (e.g. 'en', 'hindi', 'sawahi', 'taglo', 'tamil')" }, { "name": "Accept-Language", "in": "header", "schema": { "type": "string" }, "description": "Fallback header locale (e.g. 'en', 'hi', 'sw', 'tl', 'ta')" }, { "name": "search", "in": "query", "schema": { "type": "string" }, "description": "Search keyword to filter languages by name or code" }, { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 }, "description": "Page number for pagination" }, { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 500 }, "description": "Number of languages to return per page." } ], "responses": { "200": { "description": "Languages list retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "languages": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string", "example": "en" }, "name": { "type": "string", "example": "English" } } } }, "pagination": { "type": "object", "properties": { "total": { "type": "integer", "example": 22 }, "per_page": { "type": "integer", "example": 15 }, "current_page": { "type": "integer", "example": 1 }, "last_page": { "type": "integer", "example": 2 } } } } } } } } } } } } }, "/preferred-locations": { "get": { "tags": [ "General" ], "summary": "Get Localized Preferred Locations List", "description": "Returns a list of preferred locations (Dubai, Abu Dhabi, Oman) translated to the requested language. Supports en, hindi (hi), sawahi (sw), taglo (tl), tamil (ta).", "security": [], "parameters": [ { "name": "lang", "in": "query", "schema": { "type": "string", "default": "en" }, "description": "Language locale code (e.g. 'en', 'hindi', 'sawahi', 'taglo', 'tamil')" }, { "name": "Accept-Language", "in": "header", "schema": { "type": "string" }, "description": "Fallback header locale (e.g. 'en', 'hi', 'sw', 'tl', 'ta')" }, { "name": "search", "in": "query", "schema": { "type": "string" }, "description": "Search keyword to filter locations by name or code" }, { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 }, "description": "Page number for pagination" }, { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 15 }, "description": "Number of locations to return per page" } ], "responses": { "200": { "description": "Preferred locations list retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "preferred_locations": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string", "example": "dubai" }, "name": { "type": "string", "example": "Dubai" } } } }, "pagination": { "type": "object", "properties": { "total": { "type": "integer", "example": 3 }, "per_page": { "type": "integer", "example": 15 }, "current_page": { "type": "integer", "example": 1 }, "last_page": { "type": "integer", "example": 1 } } } } } } } } } } } } }, "/preferred-locations/{location}/areas": { "get": { "tags": [ "General" ], "summary": "Get Localized Areas for a Preferred Location (Path Parameter)", "description": "Returns a list of localized neighborhoods or sub-locations mapped under a specific preferred location (Dubai, Abu Dhabi, Oman) using path routing.", "security": [], "parameters": [ { "name": "location", "in": "path", "required": true, "description": "The preferred location name (e.g. dubai, abu dhabi, oman).", "schema": { "type": "string" } }, { "name": "lang", "in": "query", "schema": { "type": "string", "default": "en" }, "description": "Language locale code (e.g. 'en', 'hindi', 'sawahi', 'taglo', 'tamil')" }, { "name": "Accept-Language", "in": "header", "schema": { "type": "string" }, "description": "Fallback header locale (e.g. 'en', 'hi', 'sw', 'tl', 'ta')" }, { "name": "search", "in": "query", "schema": { "type": "string" }, "description": "Search keyword to filter areas by name or code" }, { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 }, "description": "Page number for pagination" }, { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 15 }, "description": "Number of areas to return per page" } ], "responses": { "200": { "description": "Areas retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "location": { "type": "string", "example": "dubai" }, "areas": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string", "example": "marina" }, "name": { "type": "string", "example": "Dubai Marina" } } } }, "pagination": { "type": "object", "properties": { "total": { "type": "integer", "example": 17 }, "per_page": { "type": "integer", "example": 15 }, "current_page": { "type": "integer", "example": 1 }, "last_page": { "type": "integer", "example": 2 } } } } } } } } } } } } }, "/preferred-locations/areas": { "get": { "tags": [ "General" ], "summary": "Get Localized Areas for a Preferred Location (Query Parameter)", "description": "Returns a list of localized neighborhoods or sub-locations mapped under a specific preferred location (Dubai, Abu Dhabi, Oman) using query parameter routing.", "security": [], "parameters": [ { "name": "city", "in": "query", "required": false, "description": "The preferred location name (e.g. dubai, abu dhabi, oman).", "schema": { "type": "string" } }, { "name": "location", "in": "query", "required": false, "description": "Alternative key for location name (e.g. dubai, abu dhabi, oman).", "schema": { "type": "string" } }, { "name": "lang", "in": "query", "schema": { "type": "string", "default": "en" }, "description": "Language locale code (e.g. 'en', 'hindi', 'sawahi', 'taglo', 'tamil')" }, { "name": "Accept-Language", "in": "header", "schema": { "type": "string" }, "description": "Fallback header locale (e.g. 'en', 'hi', 'sw', 'tl', 'ta')" }, { "name": "search", "in": "query", "schema": { "type": "string" }, "description": "Search keyword to filter areas by name or code" }, { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 }, "description": "Page number for pagination" }, { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 15 }, "description": "Number of areas to return per page" } ], "responses": { "200": { "description": "Areas retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "location": { "type": "string", "example": "dubai" }, "areas": { "type": "array", "items": { "type": "object", "properties": { "code": { "type": "string", "example": "marina" }, "name": { "type": "string", "example": "Dubai Marina" } } } }, "pagination": { "type": "object", "properties": { "total": { "type": "integer", "example": 17 }, "per_page": { "type": "integer", "example": 15 }, "current_page": { "type": "integer", "example": 1 }, "last_page": { "type": "integer", "example": 2 } } } } } } } } } } } } }, "/workers/send-otp": { "post": { "tags": [ "Worker/Auth" ], "summary": "Send Mobile OTP Verification Code", "description": "Dispatches a mock 6-digit OTP verification code ('111111') to the worker's mobile phone number or email address.", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "phone" ], "properties": { "phone": { "type": "string", "example": "+971501234567", "description": "Mobile contact phone number or identifier." } } } } } }, "responses": { "200": { "description": "OTP dispatched successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Verification code sent. (Dev mock: 111111)" }, "identifier": { "type": "string", "example": "+971501234567" } } } } } } } } }, "/workers/verify-otp": { "post": { "tags": [ "Worker/Auth" ], "summary": "Verify Mobile OTP Code", "description": "Validates the received 6-digit OTP code against the cached record. Sets a 1-hour secure gate allowing profile setup.", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "phone", "otp" ], "properties": { "phone": { "type": "string", "example": "+971501234567" }, "otp": { "type": "string", "example": "111111", "description": "6-digit OTP received by the worker." } } } } } }, "responses": { "200": { "description": "OTP verified and registration gate unlocked.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "OTP verified successfully. You may proceed with profile setup." }, "identifier": { "type": "string", "example": "+971501234567" } } } } } }, "422": { "description": "Invalid OTP code or expired session." } } } }, "/workers/setup-profile": { "post": { "tags": [ "Worker/Auth" ], "summary": "Complete Basic Profile Setup", "description": "Saves basic onboarding data (Name, Nationality, Language, Skills) and generates the permanent worker account along with a secure bearer access token.", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "phone", "name", "nationality", "language" ], "properties": { "phone": { "type": "string", "example": "+971501234567" }, "name": { "type": "string", "example": "Rahul Sharma" }, "nationality": { "type": "string", "example": "Indian" }, "language": { "type": "string", "enum": [ "HI", "SW", "TL", "TA" ], "example": "HI" }, "skills": { "type": "array", "items": { "type": "integer" }, "example": [ 6, 8 ], "description": "Array of skill IDs" }, "gender": { "type": "string", "enum": [ "male", "female", "other" ], "example": "male", "description": "Gender of the worker (male, female, other)." }, "live_in_out": { "type": "string", "enum": [ "live_in", "live_out" ], "example": "live_out", "description": "Accommodation preference (live_in, live_out)." }, "preferred_location": { "type": "string", "example": "Dubai Marina", "description": "Preferred work location/area." }, "main_profession": { "type": "string", "example": "Nanny", "description": "Main profession of the worker selected from the master dropdown.", "enum": [ "Housemaid", "Nanny", "Cook", "Driver", "Caregiver" ] }, "fcm_token": { "type": "string", "example": "fcm_token_example", "description": "Firebase Cloud Messaging token for push notifications." } } } } } }, "responses": { "201": { "description": "Account created and profile configured successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Registration complete! Welcome to Migrant." }, "data": { "type": "object", "properties": { "worker": { "$ref": "#/components/schemas/Worker" }, "token": { "type": "string", "example": "abc123xyz456...secureToken..." } } } } } } } } } } }, "/workers/profile": { "get": { "tags": [ "Worker/Profile" ], "summary": "Get Profile details", "description": "Retrieves the authenticated worker's profile details including their selected job category, connected skills, and uploaded documents.", "responses": { "200": { "description": "Worker profile details retrieved.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "worker": { "$ref": "#/components/schemas/Worker" } } } } } } } } } } }, "/workers/profile/update": { "post": { "tags": [ "Worker/Profile" ], "summary": "Update Profile details", "description": "Allows workers to customize and complete their profiles by updating name, phone, age, nationality, desired salary, language, preferred job type, live in/out accommodation preference, preferred location, experience, skills list, fcm_token, passport details, and visa details.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "name": { "type": "string", "example": "Amina Al-Masry" }, "phone": { "type": "string", "example": "+971509998888" }, "age": { "type": "integer", "example": 28 }, "nationality": { "type": "string", "example": "Egypt" }, "language": { "type": "string", "enum": [ "HI", "SW", "TL", "TA" ], "example": "HI" }, "salary": { "type": "number", "example": 1800 }, "preferred_job_type": { "type": "string", "example": "full-time", "description": "Preferred job type (e.g., full-time, part-time)." }, "live_in_out": { "type": "string", "enum": [ "live_in", "live_out" ], "example": "live_out", "description": "Accommodation preference (live_in, live_out)." }, "preferred_location": { "type": "string", "example": "Dubai Marina", "description": "Preferred work location/area." }, "experience": { "type": "string", "example": "4 Years" }, "skills": { "type": "array", "items": { "type": "integer" }, "example": [ 6, 8 ] }, "fcm_token": { "type": "string", "example": "fcm-device-token-xyz-123", "description": "Firebase Cloud Messaging token for push notifications." }, "passport": { "type": "object", "properties": { "passport_number": { "type": "string", "example": "ABC123456" }, "date_of_expiry": { "type": "string", "example": "2030-01-01" }, "date_of_issue": { "type": "string", "example": "2020-01-01" } } }, "visa": { "type": "object", "description": "Standardized UAE Visa metadata.", "properties": { "document_type": { "type": "string", "example": "uae_visa" }, "country": { "type": "string", "example": "United Arab Emirates" }, "visa_type": { "type": "string", "example": "ENTRY PERMIT" }, "entry_permit_no": { "type": "string", "example": "87654091 / 2016 / 210" }, "issue_date": { "type": "string", "example": "2016-11-18" }, "valid_until": { "type": "string", "example": "2017-01-18" }, "uid_no": { "type": "string", "example": "181825009" }, "full_name": { "type": "string", "example": "GILBERT DSOUZA W/O TIMOTHY" }, "nationality": { "type": "string", "example": "INDIAN" }, "place_of_birth": { "type": "string", "example": "MANGALORE" }, "date_of_birth": { "type": "string", "example": "1980-02-02" }, "passport_no": { "type": "string", "example": "U4690639" }, "profession": { "type": "string", "example": "BUSINESS PERSON" }, "sponsor_name": { "type": "string", "example": "Sponsor LLC" }, "sponsor": { "type": "object", "properties": { "name": { "type": "string", "example": "Sponsor LLC" }, "address": { "type": "string", "example": "Dubai Marina, Dubai" }, "phone": { "type": "string", "example": "2977725" } } } } } } } } } }, "responses": { "200": { "description": "Profile updated successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Profile updated successfully." }, "data": { "type": "object", "properties": { "worker": { "$ref": "#/components/schemas/Worker" } } } } } } } } } } }, "/workers/go-live": { "post": { "tags": [ "Worker/Profile" ], "summary": "Profile Go Live", "description": "Sets the worker status to 'active' and availability to 'Immediate', making the profile searchable on the sponsor/employer marketplace.", "responses": { "200": { "description": "Worker profile is now live and searchable.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Your profile is now live! Status set to Active." } } } } } } } } }, "/workers/profile/toggle-availability": { "post": { "tags": [ "Worker/Profile" ], "summary": "Toggle Profile Search Visibility", "description": "Updates worker search visibility based on whether they are still actively seeking a job. 'still_looking' as true makes profile active, false hides it.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "still_looking" ], "properties": { "still_looking": { "type": "boolean", "example": true, "description": "Whether the worker is still actively looking for job offers." } } } } } }, "responses": { "200": { "description": "Availability toggled successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "still_looking": { "type": "boolean", "example": true }, "status": { "type": "string", "example": "active" } } } } } } } } }, "/workers/profile/mark-hired": { "post": { "tags": [ "Worker/Profile" ], "summary": "Mark Worker as Hired", "description": "Changes the worker's status to 'Hired', which automatically removes them from active marketplace searches.", "responses": { "200": { "description": "Worker marked as Hired.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Congratulations! You have been successfully marked as Hired." } } } } } } } } }, "/workers/offers": { "get": { "tags": [ "Worker/Offers" ], "summary": "View Received Job Offers", "description": "Returns a list of all custom job/hiring offers received by the worker from different employers (e.g. Work Date, location, salaries, and notes).", "responses": { "200": { "description": "List of job offers retrieved.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "offers": { "type": "array", "items": { "$ref": "#/components/schemas/JobOffer" } } } } } } } } } } } }, "/workers/offers/{id}/respond": { "post": { "tags": [ "Worker/Offers" ], "summary": "Accept or Reject Job Offer", "description": "Responds to a pending job offer. If accepted, the job offer status becomes 'accepted' and the worker's status is automatically changed to 'Hired', which reflects immediately in the Employer panel.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "The Job Offer ID reference.", "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "status" ], "properties": { "status": { "type": "string", "enum": [ "accepted", "rejected" ], "example": "accepted", "description": "Response action (accepted or rejected)." } } } } } }, "responses": { "200": { "description": "Job offer response saved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Job offer successfully accepted." }, "data": { "type": "object", "properties": { "offer": { "$ref": "#/components/schemas/JobOffer" }, "worker_status": { "type": "string", "example": "Hired" } } } } } } } } } } }, "/workers/conversations": { "get": { "tags": [ "Worker/Conversations" ], "summary": "Get Conversations List (Worker)", "description": "Retrieves all active conversations for the authenticated worker.", "responses": { "200": { "description": "Conversations list retrieved successfully." } } } }, "/workers/conversations/{id}/messages": { "get": { "tags": [ "Worker/Conversations" ], "summary": "Get Conversation Messages (Worker)", "description": "Retrieves message history for a conversation and marks incoming employer messages as read.", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Messages retrieved successfully." } } }, "post": { "tags": [ "Worker/Conversations" ], "summary": "Send Reply Message (Worker)", "description": "Sends a reply message from the worker to the employer.", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "text": { "type": "string", "example": "Yes, I am available.", "description": "Optional text message content (required if no file is uploaded)." }, "file": { "type": "string", "format": "binary", "description": "Optional file or voice note attachment (Max 10MB). Supports images, documents, and common audio formats." } } } } } }, "responses": { "201": { "description": "Message sent successfully." } } } }, "/workers/report": { "post": { "tags": [ "Worker/Profile" ], "summary": "Submit a Safety/Moderation Report (Worker)", "description": "Submits a report on a chat conversation or a review. The report is logged in the safety queue and reviewed by administrators.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "type", "item_id", "reason" ], "properties": { "type": { "type": "string", "enum": [ "Chat", "Review" ], "example": "Chat", "description": "The type of entity being reported (Chat or Review)." }, "item_id": { "type": "string", "example": "1", "description": "The ID of the conversation or review being reported." }, "user_id": { "type": "string", "example": "5", "description": "Optional ID of the user being reported." }, "reason": { "type": "string", "example": "Others", "description": "The reason for submitting this report." }, "others": { "type": "string", "example": "Spam and malicious links", "description": "Custom reason string. Used only if reason is 'Others'." }, "description": { "type": "string", "example": "The other party sent highly inappropriate and insulting messages.", "description": "Optional detailed explanation/comments." } } } } } }, "responses": { "201": { "description": "Report submitted successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Report submitted successfully. Our safety team will review it shortly." }, "report_id": { "type": "string", "example": "REP-ABCD1234" } } } } } }, "404": { "description": "Conversation or Review not found, or user is not authorized to report it." }, "422": { "description": "Validation error." } } } }, "/workers/report-reasons": { "get": { "tags": [ "Worker/Profile" ], "summary": "Get Safety Report Reasons (Worker)", "description": "Returns a list of active safety/moderation report reasons. Can filter reasons by target type (Chat or Support).", "parameters": [ { "name": "type", "in": "query", "required": false, "description": "Optional type to filter reasons (Chat or Support). Case-insensitive.", "schema": { "type": "string", "enum": [ "Chat", "Support", "chat", "support" ] } } ], "responses": { "200": { "description": "List of report reasons retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "reasons": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "example": 1 }, "reason": { "type": "string", "example": "Abusive language / Profanity" }, "type": { "type": "string", "example": "Both" } } } } } } } } } } } }, "/workers/tickets": { "get": { "tags": [ "Worker/Support" ], "summary": "List Support Tickets (Worker)", "description": "Retrieves a paginated list of all support tickets created by the authenticated worker.", "responses": { "200": { "description": "Tickets retrieved successfully." } } }, "post": { "tags": [ "Worker/Support" ], "summary": "Create Support Ticket (Worker)", "description": "Creates a support ticket for a worker with a subject, description, and optional priority level.", "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "required": [ "subject", "description" ], "properties": { "subject": { "type": "string", "example": "App login crashes on launch" }, "description": { "type": "string", "example": "When opening the app on my phone, it crashes immediately on the splash screen." }, "priority": { "type": "string", "enum": [ "low", "medium", "high" ], "example": "medium" }, "reason_id": { "type": "integer", "example": 1, "description": "Optional report/support reason ID." }, "voice_note": { "type": "string", "format": "binary", "description": "Optional audio/voice note file attachment." } } } } } }, "responses": { "201": { "description": "Ticket created successfully." } } } }, "/workers/tickets/{id}": { "get": { "tags": [ "Worker/Support" ], "summary": "Get Support Ticket Details & Replies (Worker)", "description": "Retrieves the details of a support ticket and its chronological reply history.", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Ticket details and replies retrieved successfully." } } } }, "/workers/tickets/{id}/reply": { "post": { "tags": [ "Worker/Support" ], "summary": "Reply to Support Ticket (Worker)", "description": "Submits a text reply or message to an active, open, or resolved support ticket.", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "I tried clearing cache and it still crashes." }, "voice_note": { "type": "string", "format": "binary", "description": "Optional audio/voice note file attachment." } } } } } }, "responses": { "201": { "description": "Reply posted successfully." } } } }, "/workers/reviews": { "get": { "tags": [ "Worker/Reviews" ], "summary": "List Worker Reviews", "description": "Retrieves a paginated list of all reviews submitted by the authenticated worker.", "parameters": [ { "name": "page", "in": "query", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "schema": { "type": "integer", "default": 15 } } ], "responses": { "200": { "description": "Reviews retrieved successfully." } } }, "post": { "tags": [ "Worker/Reviews" ], "summary": "Submit Review for Employer", "description": "Submits a review for an employer. Eligible only after 3 months from joining, for a confirmed hire.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "employer_id", "rating", "comment" ], "properties": { "employer_id": { "type": "integer", "example": 5, "description": "The ID of the employer (User ID)." }, "job_id": { "type": "integer", "example": 2, "description": "Optional Job ID associated with the review." }, "rating": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5, "description": "Rating out of 5 stars." }, "title": { "type": "string", "example": "Great workplace", "description": "Optional review title." }, "comment": { "type": "string", "example": "Highly supportive team and on-time salary payments.", "description": "Review comment." } } } } } }, "responses": { "201": { "description": "Review submitted successfully." }, "403": { "description": "Eligibility check failed (no confirmed hire or under 3 months since joining)." }, "422": { "description": "Validation error or duplicate review." } } } }, "/workers/reviews/{id}": { "get": { "tags": [ "Worker/Reviews" ], "summary": "Get Review Details", "description": "Retrieves the details of a specific review submitted by the worker.", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Review details retrieved successfully." }, "404": { "description": "Review not found." } } }, "put": { "tags": [ "Worker/Reviews" ], "summary": "Edit Submitted Review", "description": "Updates a review. Permitted only within a 7-day edit window from the initial submission date.", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "rating", "comment" ], "properties": { "rating": { "type": "integer", "minimum": 1, "maximum": 5, "example": 4 }, "title": { "type": "string", "example": "Good workplace" }, "comment": { "type": "string", "example": "Updating my comment with details." } } } } } }, "responses": { "200": { "description": "Review edited successfully." }, "403": { "description": "Edit option disabled because the 7-day window expired." }, "404": { "description": "Review not found." } } } }, "/employers/register": { "post": { "tags": [ "Employer/Auth" ], "summary": "Register Sponsor (Alias)", "description": "Legacy route matching the simplified sponsor registration (Name, Email, Phone) (Step 1).", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "name", "email", "phone" ], "properties": { "name": { "type": "string", "example": "Ahmad Bin Ahmed", "description": "Sponsor's full name" }, "email": { "type": "string", "example": "ahmad@example.com", "description": "Sponsor's contact email address" }, "phone": { "type": "string", "example": "+971509990001", "description": "Sponsor's mobile phone number" }, "emirates_id": { "type": "object", "description": "Optional JSON object containing extracted Emirates ID details.", "properties": { "emirates_id_number": { "type": "string", "example": "784-1988-5310327-2" }, "name": { "type": "string", "example": "Ahmad Bin Ahmed" }, "date_of_birth": { "type": "string", "example": "1990-01-01" }, "nationality": { "type": "string", "example": "Emirati" }, "issue_date": { "type": "string", "example": "2023-04-11" }, "expiry_date": { "type": "string", "example": "2028-04-11" }, "employer": { "type": "string", "example": "Federal Authority" }, "issue_place": { "type": "string", "example": "Abu Dhabi" }, "occupation": { "type": "string", "example": "Manager" }, "card_number": { "type": "string", "example": "151023946" }, "gender": { "type": "string", "example": "M" } } }, "fcm_token": { "type": "string", "example": "fcm_token_example", "description": "Firebase Cloud Messaging token for push notifications." }, "address": { "type": "string", "example": "Villa 45, Street 12", "description": "Physical address/location details." } } } } } }, "responses": { "201": { "description": "Sponsor registered successfully." } } } }, "/employers/verify": { "post": { "tags": [ "Employer/Auth" ], "summary": "Verify Sponsor Email OTP", "description": "Verifies the email address with the OTP verification code (Step 2).", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "email", "otp" ], "properties": { "email": { "type": "string", "example": "ahmad@example.com" }, "otp": { "type": "string", "example": "111111", "description": "6-digit OTP code" }, "fcm_token": { "type": "string", "example": "fcm_token_example", "description": "Firebase Cloud Messaging token for push notifications." } } } } } }, "responses": { "200": { "description": "Email verified successfully." } } } }, "/employers/payment": { "post": { "tags": [ "Employer/Auth" ], "summary": "Sponsor Subscription Payment", "description": "Submits a successful plan selection and PayTabs payment confirmation (Step 4).", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "email", "plan_id", "amount_aed", "paytabs_transaction_id" ], "properties": { "email": { "type": "string", "example": "ahmad@example.com" }, "plan_id": { "type": "string", "example": "premium" }, "amount_aed": { "type": "number", "example": 199 }, "paytabs_transaction_id": { "type": "string", "example": "TXN998877" } } } } } }, "responses": { "200": { "description": "Subscription payment confirmed." } } } }, "/employers/password": { "post": { "tags": [ "Employer/Auth" ], "summary": "Create Sponsor Account Password", "description": "Configures and finalizes the portal login password to complete registration (Step 5). Returns bearer token.", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "email", "password", "password_confirmation" ], "properties": { "email": { "type": "string", "example": "ahmad@example.com" }, "password": { "type": "string", "format": "password", "example": "Password@123" }, "password_confirmation": { "type": "string", "format": "password", "example": "Password@123" }, "fcm_token": { "type": "string", "example": "fcm_token_example", "description": "Firebase Cloud Messaging token for push notifications." } } } } } }, "responses": { "200": { "description": "Password set and registration finalized successfully." } } } }, "/employers/plans": { "get": { "tags": [ "Employer/Auth" ], "summary": "Get Available Subscription Plans", "description": "Returns details (price, features) of subscription packages available to sponsors.", "security": [], "responses": { "200": { "description": "Subscription plans list retrieved successfully." } } } }, "/employers/login": { "post": { "tags": [ "Employer/Auth" ], "summary": "Authenticate Employer or Sponsor", "description": "Unified authentication endpoint. Validates email/mobile and password, then returns a stateless Bearer token and the user's role (employer or sponsor).", "security": [], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "password" ], "properties": { "email": { "type": "string", "example": "ahmad@example.com", "description": "Email address (required if mobile is not provided)" }, "mobile": { "type": "string", "example": "+971509990001", "description": "Mobile number (required if email is not provided)" }, "password": { "type": "string", "example": "Password@123" }, "fcm_token": { "type": "string", "example": "fcm_token_example", "description": "Firebase Cloud Messaging token for push notifications." } } } } } }, "responses": { "200": { "description": "Login successful. Returns Bearer token and role.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Login successful." }, "role": { "type": "string", "example": "employer", "enum": [ "employer", "sponsor" ] }, "data": { "type": "object", "properties": { "token": { "type": "string", "example": "api_token_here" } } } } } } } } } } }, "/employers/conversations": { "get": { "tags": [ "Employer/Conversations" ], "summary": "Get Conversations List (Employer)", "description": "Retrieves all active candidate conversations for the authenticated employer.", "responses": { "200": { "description": "Conversations list retrieved successfully." } } } }, "/employers/conversations/{id}/messages": { "get": { "tags": [ "Employer/Conversations" ], "summary": "Get Conversation Messages (Employer)", "description": "Retrieves message history for a conversation and marks incoming worker messages as read.", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Messages retrieved successfully." } } }, "post": { "tags": [ "Employer/Conversations" ], "summary": "Send Reply Message (Employer)", "description": "Sends a reply message from the employer to the worker.", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "text": { "type": "string", "example": "When can you start?", "description": "Optional text message content (required if no file is uploaded)." }, "file": { "type": "string", "format": "binary", "description": "Optional file or voice note attachment (Max 10MB). Supports images, documents, and common audio formats." } } } } } }, "responses": { "201": { "description": "Message sent successfully." } } } }, "/employers/conversations/start": { "post": { "tags": [ "Employer/Conversations" ], "summary": "Start Conversation with Worker", "description": "Starts or retrieves a conversation with the specified worker ID.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "worker_id" ], "properties": { "worker_id": { "type": "integer", "example": 1 } } } } } }, "responses": { "200": { "description": "Conversation started successfully." } } } }, "/workers/announcements": { "get": { "tags": [ "Worker/CharityEvents" ], "summary": "Get Charity Events (Worker)", "description": "Allows workers to retrieve the list of active charity events, food drives, and medical support programs scheduled in Dubai.", "parameters": [ { "name": "page", "in": "query", "required": false, "description": "Page number.", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "required": false, "description": "Number of items per page.", "schema": { "type": "integer", "default": 15 } } ], "responses": { "200": { "description": "List of charity events retrieved successfully." } } } }, "/workers/announcements/new": { "get": { "tags": [ "Worker/CharityEvents" ], "summary": "Get New/Unviewed Announcements/Charity Events", "description": "Retrieves up to 3 active approved charity events/announcements that the worker has not yet viewed, and automatically marks them as viewed.", "responses": { "200": { "description": "Successfully retrieved new announcements.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "example": 4 }, "title": { "type": "string", "example": "Free Dental Checkup Camp" }, "body": { "type": "string", "example": "Emirates Charity is providing free screening." }, "type": { "type": "string", "example": "charity" }, "employer_name": { "type": "string", "example": "Emirates Charity" }, "company_name": { "type": "string", "example": "Emirates Charity Foundation" }, "created_at": { "type": "string", "format": "date-time", "example": "2026-06-01T10:00:00.000000Z" }, "time_ago": { "type": "string", "example": "5 hours ago" } } } } } } } } }, "401": { "description": "Unauthenticated." } } } }, "/workers/announcements/{id}/view": { "post": { "tags": [ "Worker/CharityEvents" ], "summary": "Mark Specific Announcement as Viewed", "description": "Explicitly marks a specific announcement/charity event as viewed by the authenticated worker.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Announcement ID", "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Announcement marked as viewed successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Announcement marked as viewed." } } } } } }, "401": { "description": "Unauthenticated." }, "404": { "description": "Announcement not found." } } } }, "/workers/jobs": { "get": { "tags": [ "Worker/Jobs" ], "summary": "List Available Jobs", "description": "Returns a list of all active job postings available for workers to discover and apply.", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Available jobs retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "jobs": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "example": 1 }, "title": { "type": "string", "example": "Housekeeper Needed" }, "location": { "type": "string", "example": "Dubai Marina" }, "salary": { "type": "integer", "example": 2500 }, "workers_needed": { "type": "integer", "example": 2 }, "job_type": { "type": "string", "example": "full-time" }, "start_date": { "type": "string", "format": "date", "example": "2026-06-01", "nullable": true }, "description": { "type": "string", "example": "Looking for an experienced housekeeper..." }, "requirements": { "type": "string", "example": "Must have 2+ years of experience..." }, "company_name": { "type": "string", "example": "Ahmad Tech Ltd" }, "posted_by": { "type": "string", "example": "Jane Sponsor" }, "posted_at": { "type": "string", "format": "date-time", "example": "2026-06-30T10:13:17.000000+00:00" } } } } } } } } } } }, "401": { "description": "Unauthenticated or invalid Bearer token." } } } }, "/workers/jobs/{id}": { "get": { "tags": [ "Worker/Jobs" ], "summary": "Get Job Details", "description": "Retrieves the detailed information of a specific active job posting.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "description": "The job post ID.", "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Job details retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "job": { "type": "object", "properties": { "id": { "type": "integer", "example": 1 }, "title": { "type": "string", "example": "Housekeeper Needed" }, "location": { "type": "string", "example": "Dubai Marina" }, "salary": { "type": "integer", "example": 2500 }, "workers_needed": { "type": "integer", "example": 2 }, "job_type": { "type": "string", "example": "full-time" }, "start_date": { "type": "string", "format": "date", "example": "2026-06-01", "nullable": true }, "description": { "type": "string", "example": "Looking for an experienced housekeeper..." }, "requirements": { "type": "string", "example": "Must have 2+ years of experience..." }, "company_name": { "type": "string", "example": "Ahmad Tech Ltd" }, "posted_by": { "type": "string", "example": "Jane Sponsor" }, "posted_at": { "type": "string", "format": "date-time", "example": "2026-06-30T10:13:17.000000+00:00" } } } } } } } } } }, "401": { "description": "Unauthenticated or invalid Bearer token." }, "404": { "description": "Job not found." } } } }, "/workers/jobs/{id}/apply": { "post": { "tags": [ "Worker/Jobs" ], "summary": "Apply for a Job", "description": "Allows a worker to apply for a specific active job posting. Prevents duplicate applications from the same worker.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "description": "The job post ID.", "schema": { "type": "integer" } } ], "responses": { "201": { "description": "Successfully applied for the job.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Successfully applied for the job." }, "data": { "type": "object", "properties": { "application": { "type": "object", "properties": { "id": { "type": "integer", "example": 10 }, "worker_id": { "type": "integer", "example": 136 }, "job_id": { "type": "integer", "example": 1 }, "status": { "type": "string", "example": "applied" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } } } } } } } } }, "401": { "description": "Unauthenticated or invalid Bearer token." }, "404": { "description": "Job not found." }, "409": { "description": "Conflict - worker has already applied for this job.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "You have already applied for this job." } } } } } } } } }, "/workers/applied-jobs": { "get": { "tags": [ "Worker/Jobs" ], "summary": "Get Applied Jobs", "description": "Returns a list of all jobs the authenticated worker has applied to, along with application status.", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Applied jobs retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "applications": { "type": "array", "items": { "type": "object", "properties": { "application_id": { "type": "integer", "example": 10 }, "status": { "type": "string", "example": "applied" }, "applied_at": { "type": "string", "format": "date-time", "example": "2026-06-30T10:13:17.000000+00:00" }, "job": { "type": "object", "nullable": true, "properties": { "id": { "type": "integer", "example": 1 }, "title": { "type": "string", "example": "Housekeeper Needed" }, "location": { "type": "string", "example": "Dubai Marina" }, "salary": { "type": "integer", "example": 2500 }, "job_type": { "type": "string", "example": "full-time" }, "company_name": { "type": "string", "example": "Ahmad Tech Ltd" }, "posted_by": { "type": "string", "example": "Jane Sponsor" } } } } } } } } } } } } }, "401": { "description": "Unauthenticated or invalid Bearer token." } } } }, "/employers/announcements": { "get": { "tags": [ "Employer/CharityEvents" ], "summary": "Get Posted Charity Events (Employer)", "description": "Allows employers/sponsors to retrieve the list of charity events they have published.", "parameters": [ { "name": "page", "in": "query", "required": false, "description": "Page number.", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "required": false, "description": "Number of items per page.", "schema": { "type": "integer", "default": 15 } } ], "responses": { "200": { "description": "List of posted charity events retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "announcements": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "example": 1 }, "title": { "type": "string", "example": "Holiday Notice" }, "body": { "type": "string", "example": "Office will be closed tomorrow." }, "type": { "type": "string", "example": "info" }, "employer_name": { "type": "string", "example": "Employer One" }, "company_name": { "type": "string", "example": "Elite Services" }, "created_at": { "type": "string", "format": "date-time", "example": "2026-06-23T10:13:17.000000Z" }, "time_ago": { "type": "string", "example": "2 hours ago" }, "charity_details": { "type": "object", "nullable": true } } } }, "pagination": { "type": "object", "properties": { "total": { "type": "integer", "example": 1 }, "per_page": { "type": "integer", "example": 15 }, "current_page": { "type": "integer", "example": 1 }, "last_page": { "type": "integer", "example": 1 } } } } } } } } } } } }, "post": { "tags": [ "Employer/CharityEvents" ], "summary": "Publish Charity Event (Employer)", "description": "Allows employers/sponsors to publish a new community charity event or drive to all workers in Dubai, triggering instant push notifications and morning-of reminders.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "title", "content", "provided_items", "event_date", "event_time", "location_details", "location_pin" ], "properties": { "title": { "type": "string", "example": "Free Dental Checkup Camp" }, "content": { "type": "string", "example": "Emirates Charity is providing free professional dental screening, cleanings, and educational packages for domestic helpers." }, "provided_items": { "type": "string", "example": "Free Dental screening, cleanings, and wellness kits" }, "event_date": { "type": "string", "format": "date", "example": "2026-06-15" }, "event_time": { "type": "string", "example": "9:00 AM - 4:00 PM" }, "location_details": { "type": "string", "example": "Al Quoz Community Hall, Dubai" }, "location_pin": { "type": "string", "format": "uri", "example": "https://maps.app.goo.gl/xyz" } } } } } }, "responses": { "201": { "description": "Charity event created and notifications scheduled successfully." } } } }, "/employers/announcements/{id}": { "delete": { "tags": [ "Employer/CharityEvents" ], "summary": "Delete Charity Event (Employer)", "description": "Allows employers/sponsors to delete a previously published charity event.", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Charity event deleted successfully." } } } }, "/employers/dashboard": { "get": { "tags": [ "Employer/Profile" ], "summary": "Get Employer Dashboard stats & recent events", "description": "Retrieves stats including contacted workers count, total hired workers, saved candidates, current plan details, and recent announcements or events.", "responses": { "200": { "description": "Employer dashboard stats retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "stats": { "type": "object", "properties": { "contacted_workers_count": { "type": "integer", "example": 0 }, "total_hired_workers": { "type": "integer", "example": 0 }, "saved_candidates": { "type": "integer", "example": 0 }, "total_workers": { "type": "integer", "example": 15 } } }, "current_plan": { "type": "object", "properties": { "plan_id": { "type": "string", "example": "premium" }, "name": { "type": "string", "example": "Premium Pass" }, "status": { "type": "string", "example": "active" }, "starts_at": { "type": "string", "format": "date", "example": "2026-06-23" }, "expires_at": { "type": "string", "format": "date", "example": "2026-07-23" } } }, "recent_announcements": { "type": "array", "items": { "type": "object" } }, "recent_events": { "type": "array", "items": { "type": "object" } } } } } } } } } } } }, "/employers/profile": { "get": { "tags": [ "Employer/Profile" ], "summary": "Get Employer Profile Details", "description": "Retrieves the authenticated employer's profile details.", "responses": { "200": { "description": "Profile retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "profile": { "type": "object", "properties": { "name": { "type": "string", "example": "Ahmad" }, "email": { "type": "string", "example": "ahmad@example.com" }, "phone": { "type": "string", "example": "+971509990001" }, "address": { "type": "string", "example": "Villa 12, Jumeirah 2" }, "notifications": { "type": "boolean", "example": true }, "verification_status": { "type": "string", "example": "approved" }, "emirates_id_number": { "type": "string", "example": "784-1988-5310327-2" }, "emirates_id_expiry": { "type": "string", "example": "2028-04-11" }, "id_number": { "type": "string", "example": "784-1987-5493842-5" }, "card_number": { "type": "string", "example": "151023946" }, "full_name": { "type": "string", "example": "Mohammad Jobaier Mohammad Abul Kalam" }, "date_of_birth": { "type": "string", "example": "14/04/1987" }, "nationality": { "type": "string", "example": "Bangladesh" }, "gender": { "type": "string", "example": "M" }, "issue_date": { "type": "string", "example": "12/12/2025" }, "expiry_date": { "type": "string", "example": "11/12/2027" }, "occupation": { "type": "string", "example": "Electrician" }, "employer": { "type": "string", "example": "Msj International Technical Services L.L.C UAE" }, "issuing_place": { "type": "string", "example": "Dubai" }, "emirates_id": { "type": "object", "description": "Consolidated Emirates ID details.", "properties": { "emirates_id_number": { "type": "string", "example": "784-1988-5310327-2" }, "name": { "type": "string", "example": "Ahmad Bin Ahmed" }, "date_of_birth": { "type": "string", "example": "1990-01-01" }, "nationality": { "type": "string", "example": "Emirati" }, "issue_date": { "type": "string", "example": "2023-04-11" }, "expiry_date": { "type": "string", "example": "2028-04-11" }, "employer": { "type": "string", "example": "Federal Authority" }, "issue_place": { "type": "string", "example": "Abu Dhabi" }, "occupation": { "type": "string", "example": "Manager" }, "card_number": { "type": "string", "example": "151023946" }, "gender": { "type": "string", "example": "M" } } } } } } } } } } } } } } }, "/employers/profile/update": { "post": { "tags": [ "Employer/Profile" ], "summary": "Update Employer Profile Details", "description": "Updates the authenticated employer's profile details including optional Emirates ID metadata. Password changes are not supported via this endpoint.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "name", "email", "phone", "address" ], "properties": { "name": { "type": "string", "example": "Ahmad" }, "email": { "type": "string", "example": "ahmad@example.com" }, "phone": { "type": "string", "example": "+971509990001" }, "address": { "type": "string", "example": "Villa 12, Jumeirah 2" }, "notifications": { "type": "boolean", "example": true, "description": "Optional. Enable/disable push notifications. Defaults to true if not provided.", "default": true }, "fcm_token": { "type": "string", "example": "fcm_token_example", "description": "Firebase Cloud Messaging token for push notifications." }, "id_number": { "type": "string", "example": "784-1987-5493842-5", "description": "Emirates ID card number/ID number (optional)" }, "card_number": { "type": "string", "example": "151023946", "description": "Emirates ID card physical serial number (optional)" }, "full_name": { "type": "string", "example": "Mohammad Jobaier Mohammad Abul Kalam", "description": "Emirates ID full name (optional)" }, "date_of_birth": { "type": "string", "example": "14/04/1987", "description": "Emirates ID date of birth (optional)" }, "nationality": { "type": "string", "example": "Bangladesh", "description": "Emirates ID nationality (optional)" }, "gender": { "type": "string", "example": "M", "description": "Emirates ID gender (optional)" }, "issue_date": { "type": "string", "example": "12/12/2025", "description": "Emirates ID card issue date (optional)" }, "expiry_date": { "type": "string", "example": "11/12/2027", "description": "Emirates ID card expiry date (optional)" }, "occupation": { "type": "string", "example": "Electrician", "description": "Emirates ID card holder occupation (optional)" }, "employer": { "type": "string", "example": "Msj International Technical Services L.L.C UAE", "description": "Emirates ID card holder sponsor/employer name (optional)" }, "issuing_place": { "type": "string", "example": "Dubai", "description": "Emirates ID card place of issue (optional)" } } } } } }, "responses": { "200": { "description": "Profile updated successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Profile updated successfully." }, "data": { "type": "object", "properties": { "profile": { "type": "object", "properties": { "name": { "type": "string", "example": "Ahmad" }, "email": { "type": "string", "example": "ahmad@example.com" }, "phone": { "type": "string", "example": "+971509990001" }, "address": { "type": "string", "example": "Villa 12, Jumeirah 2" }, "notifications": { "type": "boolean", "example": true }, "verification_status": { "type": "string", "example": "approved" }, "emirates_id_number": { "type": "string", "example": "784-1988-5310327-2" }, "emirates_id_expiry": { "type": "string", "example": "2028-04-11" }, "id_number": { "type": "string", "example": "784-1987-5493842-5" }, "card_number": { "type": "string", "example": "151023946" }, "full_name": { "type": "string", "example": "Mohammad Jobaier Mohammad Abul Kalam" }, "date_of_birth": { "type": "string", "example": "14/04/1987" }, "nationality": { "type": "string", "example": "Bangladesh" }, "gender": { "type": "string", "example": "M" }, "issue_date": { "type": "string", "example": "12/12/2025" }, "expiry_date": { "type": "string", "example": "11/12/2027" }, "occupation": { "type": "string", "example": "Electrician" }, "employer": { "type": "string", "example": "Msj International Technical Services L.L.C UAE" }, "issuing_place": { "type": "string", "example": "Dubai" }, "emirates_id": { "type": "object", "description": "Consolidated Emirates ID details.", "properties": { "emirates_id_number": { "type": "string", "example": "784-1988-5310327-2" }, "name": { "type": "string", "example": "Ahmad Bin Ahmed" }, "date_of_birth": { "type": "string", "example": "1990-01-01" }, "nationality": { "type": "string", "example": "Emirati" }, "issue_date": { "type": "string", "example": "2023-04-11" }, "expiry_date": { "type": "string", "example": "2028-04-11" }, "employer": { "type": "string", "example": "Federal Authority" }, "issue_place": { "type": "string", "example": "Abu Dhabi" }, "occupation": { "type": "string", "example": "Manager" }, "card_number": { "type": "string", "example": "151023946" }, "gender": { "type": "string", "example": "M" } } } } } } } } } } } }, "422": { "description": "Validation error." } } } }, "/employers/workers": { "get": { "tags": [ "Employer/Pipeline" ], "summary": "Get Available Workers", "description": "Returns a list of verified workers that are currently available to be hired.", "parameters": [ { "name": "search", "in": "query", "required": false, "description": "Search term matching helper name, nationality, or religion.", "schema": { "type": "string" } }, { "name": "skills", "in": "query", "required": false, "description": "Filter by skills (comma-separated list).", "schema": { "type": "string" } }, { "name": "language", "in": "query", "required": false, "description": "Filter by language.", "schema": { "type": "string" } }, { "name": "nationality", "in": "query", "required": false, "description": "Filter by nationality name (comma-separated list for multiple choice, e.g. Indian,Kenyan,Ethiopian).", "schema": { "type": "string" } }, { "name": "gender", "in": "query", "required": false, "description": "Filter by gender (e.g. male, female).", "schema": { "type": "string" } }, { "name": "main_profession", "in": "query", "required": false, "description": "Filter by main profession (e.g. Housemaid, Nanny, Cook, Driver, Caregiver).", "schema": { "type": "string" } }, { "name": "preferred_location", "in": "query", "required": false, "description": "Filter by preferred location (comma-separated list, e.g. Dubai,Abu Dhabi).", "schema": { "type": "string" } }, { "name": "area", "in": "query", "required": false, "description": "Filter by preferred area (comma-separated list, e.g. Marina,Al Barsha).", "schema": { "type": "string" } }, { "name": "job_type", "in": "query", "required": false, "description": "Filter by job type (comma-separated list, e.g. full-time,part-time).", "schema": { "type": "string" } }, { "name": "accommodation_type", "in": "query", "required": false, "description": "Filter by accommodation type (comma-separated list, e.g. live_in,live_out).", "schema": { "type": "string" } }, { "name": "in_country", "in": "query", "required": false, "description": "Filter by in country status (true/false or yes/no or in/out).", "schema": { "type": "string" } }, { "name": "out_country", "in": "query", "required": false, "description": "Filter by out country status (true/false or yes/no or out/in).", "schema": { "type": "string" } }, { "name": "visa_status", "in": "query", "required": false, "description": "Filter by next visa status (comma-separated list, e.g. Residence Visa,Tourist Visa). Only applicable if in country.", "schema": { "type": "string" } }, { "name": "availability", "in": "query", "required": false, "description": "Filter by availability status.", "schema": { "type": "string" } }, { "name": "page", "in": "query", "required": false, "description": "Page number.", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "required": false, "description": "Number of items per page.", "schema": { "type": "integer", "default": 15 } } ], "responses": { "200": { "description": "Available workers list retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "workers": { "type": "array", "items": { "$ref": "#/components/schemas/Worker" } }, "pagination": { "type": "object", "properties": { "total": { "type": "integer", "example": 12 }, "per_page": { "type": "integer", "example": 15 }, "current_page": { "type": "integer", "example": 1 }, "last_page": { "type": "integer", "example": 1 } } } } } } } } } } } } }, "/employers/workers/{id}": { "get": { "tags": [ "Employer/Pipeline" ], "summary": "Get Worker Profile Detail", "description": "Retrieves the complete profile details for a worker, mirroring the web detailed view, along with active conversation details if already started with this employer.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Worker ID reference.", "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Worker profile details retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "worker": { "allOf": [ { "$ref": "#/components/schemas/Worker" }, { "type": "object", "properties": { "reviews": { "type": "array", "items": { "type": "object" } }, "similar_workers": { "type": "array", "items": { "type": "object" } }, "conversation_id": { "type": "integer", "nullable": true, "example": 4 } } } ] } } } } } } } }, "404": { "description": "Worker profile not found." } } } }, "/employers/candidates": { "get": { "tags": [ "Employer/Pipeline" ], "summary": "Get Candidate Applications and Offers", "description": "Returns all job applications and direct hiring offers connected to the authenticated sponsor account that have achieved 'Hired' status.", "parameters": [ { "name": "search", "in": "query", "required": false, "description": "Search term matching helper name, nationality, or religion.", "schema": { "type": "string" } }, { "name": "skills", "in": "query", "required": false, "description": "Filter candidates by skills (comma-separated list of skill names, e.g. cooking,driving).", "schema": { "type": "string" } }, { "name": "languages", "in": "query", "required": false, "description": "Filter candidates by languages spoken (comma-separated list of language names, e.g. English,Arabic).", "schema": { "type": "string" } }, { "name": "nationality", "in": "query", "required": false, "description": "Filter candidates by nationality name (comma-separated list for multiple choice, e.g. Indian,Kenyan,Ethiopian).", "schema": { "type": "string" } }, { "name": "gender", "in": "query", "required": false, "description": "Filter candidates by gender (e.g. male, female).", "schema": { "type": "string" } }, { "name": "preferred_location", "in": "query", "required": false, "description": "Filter candidates by preferred location (comma-separated list, e.g. Dubai,Abu Dhabi).", "schema": { "type": "string" } }, { "name": "job_type", "in": "query", "required": false, "description": "Filter candidates by job type (comma-separated list, e.g. full-time,part-time).", "schema": { "type": "string" } }, { "name": "accommodation_type", "in": "query", "required": false, "description": "Filter candidates by accommodation type (comma-separated list, e.g. live_in,live_out).", "schema": { "type": "string" } }, { "name": "in_country", "in": "query", "required": false, "description": "Filter candidates by in country status (true/false or yes/no or in/out).", "schema": { "type": "string" } }, { "name": "out_country", "in": "query", "required": false, "description": "Filter candidates by out country status (true/false or yes/no or out/in).", "schema": { "type": "string" } }, { "name": "visa_status", "in": "query", "required": false, "description": "Filter candidates by next visa status (comma-separated list, e.g. Residence Visa,Tourist Visa). Only applicable if in country.", "schema": { "type": "string" } }, { "name": "availability", "in": "query", "required": false, "description": "Filter candidates by availability status.", "schema": { "type": "string" } }, { "name": "page", "in": "query", "required": false, "description": "Page number.", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "required": false, "description": "Number of items per page.", "schema": { "type": "integer", "default": 15 } } ], "responses": { "200": { "description": "Employer candidate pipeline retrieved successfully." } } } }, "/employers/candidates/{id}/hire": { "post": { "tags": [ "Employer/Pipeline" ], "summary": "Mark Candidate as Hired", "description": "Transitions the target candidate application, job offer, or helper status to 'Hired'.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "The target identifier (Application ID, Offer ID, or Worker ID).", "schema": { "type": "string" } } ], "responses": { "200": { "description": "Candidate successfully status updated to Hired." } } } }, "/employers/shortlist": { "get": { "tags": [ "Employer/Pipeline" ], "summary": "Get Shortlisted Workers", "description": "Returns a list of all workers shortlisted by the authenticated sponsor.", "parameters": [ { "name": "page", "in": "query", "required": false, "description": "Page number.", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "required": false, "description": "Number of items per page.", "schema": { "type": "integer", "default": 15 } } ], "responses": { "200": { "description": "Shortlisted workers retrieved successfully." } } }, "post": { "tags": [ "Employer/Pipeline" ], "summary": "Toggle Worker Shortlist Status", "description": "Toggles (adds or removes) a worker to/from the authenticated sponsor's shortlist.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "worker_id" ], "properties": { "worker_id": { "type": "integer", "example": 1, "description": "Worker ID to shortlist/unshortlist." } } } } } }, "responses": { "200": { "description": "Shortlist status toggled successfully." } } } }, "/employers/payments": { "get": { "tags": [ "Employer/Billing" ], "summary": "Get Payment History", "description": "Retrieves the complete transaction history for the authenticated sponsor/employer, including subscription passes and document verification receipts.", "parameters": [ { "name": "page", "in": "query", "required": false, "description": "Page number.", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "required": false, "description": "Number of items per page.", "schema": { "type": "integer", "default": 15 } } ], "responses": { "200": { "description": "Employer billing history retrieved successfully." } } } }, "/workers/dashboard/views": { "get": { "tags": [ "Worker/Dashboard" ], "summary": "Get Worker Profile Views Statistics", "description": "Allows authenticated workers to see the total count and detailed list of employers/sponsors who viewed their full profile.", "responses": { "200": { "description": "Profile views statistics retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "views_count": { "type": "integer", "example": 5 }, "views_list": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "example": 1 }, "employer_id": { "type": "integer", "example": 2 }, "employer_name": { "type": "string", "example": "Ahmad" }, "company_name": { "type": "string", "example": "Ahmad Tech Ltd" }, "nationality": { "type": "string", "example": "UAE" }, "city": { "type": "string", "example": "Dubai" }, "viewed_at": { "type": "string", "format": "date-time", "example": "2026-06-01T15:10:24.000000Z" }, "viewed_at_formatted": { "type": "string", "example": "2 minutes ago" } } } } } } } } } } } } } }, "/workers/dashboard": { "get": { "tags": [ "Worker/Dashboard" ], "summary": "Get Worker Consolidated Dashboard Data", "description": "Allows authenticated workers to retrieve their dashboard metrics: active status, profile views count, currently working sponsor/employer details, and latest charity events/announcements.", "responses": { "200": { "description": "Worker dashboard details retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "active_status": { "type": "string", "example": "active" }, "count_sponsors_viewed": { "type": "integer", "example": 5 }, "employer_contacted": { "type": "integer", "example": 2, "description": "Unique count of employers who contacted this worker." }, "profile_viewed": { "type": "integer", "example": 3, "description": "Unique count of employers who viewed this worker's profile." }, "currently_working_sponsor": { "type": "object", "nullable": true, "properties": { "id": { "type": "integer", "example": 2 }, "name": { "type": "string", "example": "Ahmad" }, "company_name": { "type": "string", "example": "Ahmad Tech Ltd" }, "nationality": { "type": "string", "example": "UAE" }, "city": { "type": "string", "example": "Dubai" }, "email": { "type": "string", "example": "ahmad@example.com" }, "phone": { "type": "string", "example": "+971509990001" }, "hired_at": { "type": "string", "format": "date-time", "example": "2026-06-01T15:10:24.000000Z" }, "hired_at_formatted": { "type": "string", "example": "Jun 01, 2026" } } }, "latest_charity_events_list": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "example": 1 }, "title": { "type": "string", "example": "Free Dental Checkup Camp" }, "body": { "type": "string", "example": "Emirates Charity is providing free screening." }, "type": { "type": "string", "example": "charity" }, "employer_name": { "type": "string", "example": "Emirates Charity" }, "company_name": { "type": "string", "example": "Emirates Charity Foundation" }, "created_at": { "type": "string", "format": "date-time", "example": "2026-06-01T10:00:00.000000Z" }, "time_ago": { "type": "string", "example": "5 hours ago" } } } } } } } } } } } } } }, "/employers/reviews": { "get": { "tags": [ "Employer/Reviews" ], "summary": "Get Reviews Written by Employer", "description": "Retrieves a paginated list of all reviews written by the authenticated employer.", "parameters": [ { "name": "page", "in": "query", "required": false, "description": "Page number.", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "required": false, "description": "Number of items per page.", "schema": { "type": "integer", "default": 15 } } ], "responses": { "200": { "description": "Reviews retrieved successfully." } } }, "post": { "tags": [ "Employer/Reviews" ], "summary": "Add or Update Worker Review", "description": "Allows employers to submit a review score and description comment for a worker. If the employer has already left a review, this will update it.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "worker_id", "rating" ], "properties": { "worker_id": { "type": "integer", "example": 136, "description": "Worker ID being reviewed." }, "rating": { "type": "integer", "minimum": 1, "maximum": 5, "example": 5, "description": "Review score from 1 to 5." }, "comment": { "type": "string", "example": "Highly professional, punctual and did a great job!", "description": "Optional detailed comment." } } } } } }, "responses": { "200": { "description": "Review updated successfully." }, "201": { "description": "Review added successfully." }, "422": { "description": "Validation error." } } } }, "/employers/reviews/{id}": { "put": { "tags": [ "Employer/Reviews" ], "summary": "Edit Worker Review", "description": "Allows employers to edit their previously created review score and comment by review ID.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "Review ID reference.", "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "rating" ], "properties": { "rating": { "type": "integer", "minimum": 1, "maximum": 5, "example": 4, "description": "Updated rating score from 1 to 5." }, "comment": { "type": "string", "example": "Updated feedback comment.", "description": "Updated review comment description." } } } } } }, "responses": { "200": { "description": "Review edited successfully." }, "404": { "description": "Review not found or unauthorized." }, "422": { "description": "Validation error." } } } }, "/employers/report": { "post": { "tags": [ "Employer/Reviews" ], "summary": "Submit a Safety/Moderation Report (Employer)", "description": "Submits a report on a chat conversation or a review. The report is logged in the safety queue and reviewed by administrators.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "type", "item_id", "reason" ], "properties": { "type": { "type": "string", "enum": [ "Chat", "Review" ], "example": "Chat", "description": "The type of entity being reported (Chat or Review)." }, "item_id": { "type": "string", "example": "1", "description": "The ID of the conversation or review being reported." }, "user_id": { "type": "string", "example": "5", "description": "Optional ID of the user being reported." }, "reason": { "type": "string", "example": "Others", "description": "The reason for submitting this report." }, "others": { "type": "string", "example": "Spam and malicious links", "description": "Custom reason string. Used only if reason is 'Others'." }, "description": { "type": "string", "example": "The worker requested payments off-platform and sent abusive messages.", "description": "Optional detailed explanation/comments." } } } } } }, "responses": { "201": { "description": "Report submitted successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Report submitted successfully. Our safety team will review it shortly." }, "report_id": { "type": "string", "example": "REP-ABCD1234" } } } } } }, "404": { "description": "Conversation or Review not found, or user is not authorized to report it." }, "422": { "description": "Validation error." } } } }, "/employers/report-reasons": { "get": { "tags": [ "Employer/Reviews" ], "summary": "Get Safety Report Reasons (Employer)", "description": "Returns a list of active safety/moderation report reasons. Can filter reasons by target type (Chat or Support).", "parameters": [ { "name": "type", "in": "query", "required": false, "description": "Optional type to filter reasons (Chat or Support). Case-insensitive.", "schema": { "type": "string", "enum": [ "Chat", "Support", "chat", "support" ] } } ], "responses": { "200": { "description": "List of report reasons retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "reasons": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "example": 1 }, "reason": { "type": "string", "example": "Abusive language / Profanity" }, "type": { "type": "string", "example": "Both" } } } } } } } } } } } }, "/employers/tickets": { "get": { "tags": [ "Employer/Support" ], "summary": "List Support Tickets (Employer)", "description": "Retrieves a paginated list of all support tickets created by the authenticated employer.", "responses": { "200": { "description": "Tickets retrieved successfully." } } }, "post": { "tags": [ "Employer/Support" ], "summary": "Create Support Ticket (Employer)", "description": "Creates a support ticket for an employer with a subject, description, and optional priority level.", "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "required": [ "subject", "description" ], "properties": { "subject": { "type": "string", "example": "Payment card rejected" }, "description": { "type": "string", "example": "My Visa card was declined when trying to buy the Premium Employer Pass." }, "priority": { "type": "string", "enum": [ "low", "medium", "high" ], "example": "medium" }, "reason_id": { "type": "integer", "example": 1, "description": "Optional report/support reason ID." }, "voice_note": { "type": "string", "format": "binary", "description": "Optional audio/voice note file attachment." } } } } } }, "responses": { "201": { "description": "Ticket created successfully." } } } }, "/employers/tickets/{id}": { "get": { "tags": [ "Employer/Support" ], "summary": "Get Support Ticket Details & Replies (Employer)", "description": "Retrieves the details of a support ticket and its chronological reply history.", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Ticket details and replies retrieved successfully." } } } }, "/employers/tickets/{id}/reply": { "post": { "tags": [ "Employer/Support" ], "summary": "Reply to Support Ticket (Employer)", "description": "Submits a text reply or message to an active, open, or resolved support ticket.", "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "multipart/form-data": { "schema": { "type": "object", "properties": { "message": { "type": "string", "example": "I tried a different card and it still fails." }, "voice_note": { "type": "string", "format": "binary", "description": "Optional audio/voice note file attachment." } } } } } }, "responses": { "201": { "description": "Reply posted successfully." } } } }, "/employers/jobs": { "get": { "tags": [ "Employer/Jobs" ], "summary": "List Employer Job Postings", "description": "Retrieves all job postings created by the authenticated employer. Enforces subscription-based premium access (disabled on basic plan).", "security": [ { "bearerAuth": [] } ], "responses": { "200": { "description": "Jobs list retrieved successfully." }, "403": { "description": "Plan does not support the Job Apply module." } } }, "post": { "tags": [ "Employer/Jobs" ], "summary": "Create Job Posting", "description": "Creates a new job posting for the employer. Enforces premium subscription plan.", "security": [ { "bearerAuth": [] } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "title", "workers_needed", "location", "salary", "job_type", "start_date", "description" ], "properties": { "title": { "type": "string", "example": "Housekeeper Needed" }, "workers_needed": { "type": "integer", "example": 2 }, "location": { "type": "string", "example": "Dubai Marina" }, "salary": { "type": "number", "example": 1800 }, "job_type": { "type": "string", "enum": [ "Full Time", "Part Time", "Contract" ], "example": "Full Time" }, "start_date": { "type": "string", "format": "date", "example": "2026-07-15" }, "description": { "type": "string", "example": "Looking for an experienced housekeeper for a family in Dubai Marina." }, "requirements": { "type": "string", "example": "Must speak fluent English. Minimum 3 years experience." } } } } } }, "responses": { "201": { "description": "Job created successfully." }, "403": { "description": "Plan does not support the Job Apply module." }, "422": { "description": "Validation error." } } } }, "/employers/jobs/{id}": { "get": { "tags": [ "Employer/Jobs" ], "summary": "Get Job Details", "description": "Retrieves the details of a specific job posting owned by the authenticated employer.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Job details retrieved successfully." }, "403": { "description": "Plan does not support the Job Apply module." }, "404": { "description": "Job not found or unauthorized." } } }, "delete": { "tags": [ "Employer/Jobs" ], "summary": "Delete Job Posting", "description": "Deletes the specified job posting owned by the authenticated employer.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Job deleted successfully." }, "403": { "description": "Plan does not support the Job Apply module." }, "404": { "description": "Job not found or unauthorized." } } } }, "/employers/jobs/{id}/update": { "post": { "tags": [ "Employer/Jobs" ], "summary": "Update Job Posting", "description": "Updates an existing job posting owned by the authenticated employer.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "title", "workers_needed", "location", "salary", "job_type", "start_date", "description", "status" ], "properties": { "title": { "type": "string", "example": "Housekeeper Needed" }, "workers_needed": { "type": "integer", "example": 2 }, "location": { "type": "string", "example": "Dubai Marina" }, "salary": { "type": "number", "example": 1800 }, "job_type": { "type": "string", "enum": [ "Full Time", "Part Time", "Contract" ], "example": "Full Time" }, "start_date": { "type": "string", "format": "date", "example": "2026-07-15" }, "description": { "type": "string", "example": "Looking for an experienced housekeeper for a family in Dubai Marina." }, "requirements": { "type": "string", "example": "Must speak fluent English. Minimum 3 years experience." }, "status": { "type": "string", "enum": [ "active", "closed", "draft" ], "example": "active" } } } } } }, "responses": { "200": { "description": "Job updated successfully." }, "403": { "description": "Plan does not support the Job Apply module." }, "404": { "description": "Job not found or unauthorized." }, "422": { "description": "Validation error." } } } }, "/employers/jobs/{id}/applicants": { "get": { "tags": [ "Employer/JobApplicants" ], "summary": "Get Job Applicants", "description": "Retrieves the list of workers who have applied for the specified job posting owned by the authenticated employer.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "description": "The job post ID.", "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Job applicants list retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "job": { "type": "object", "properties": { "id": { "type": "integer", "example": 1 }, "title": { "type": "string", "example": "Housekeeper Needed" } } }, "applicants": { "type": "array", "items": { "type": "object", "properties": { "application_id": { "type": "integer", "example": 10 }, "status": { "type": "string", "example": "applied" }, "applied_at": { "type": "string", "format": "date-time", "example": "2026-06-30T10:13:17.000000+00:00" }, "worker": { "type": "object", "nullable": true, "properties": { "id": { "type": "integer", "example": 136 }, "name": { "type": "string", "example": "Amina Al-Masry" }, "nationality": { "type": "string", "example": "Egypt" }, "salary": { "type": "integer", "example": 1500 }, "preferred_location": { "type": "string", "example": "Dubai Marina" }, "preferred_job_type": { "type": "string", "example": "full-time" }, "visa_status": { "type": "string", "example": "Tourist Visa" } } } } } } } } } } } } }, "401": { "description": "Unauthenticated or invalid Bearer token." }, "403": { "description": "Plan does not support the Job Apply module." }, "404": { "description": "Job not found or unauthorized access." } } } }, "/employers/applications/{id}/status": { "post": { "tags": [ "Employer/JobApplicants" ], "summary": "Update Job Application Status", "description": "Allows employers to update the status of a job application (e.g. shortlist, contacted, interview scheduled, selected, hired, rejected) with optional internal notes. Subscription limits (contact limits) are enforced when moving a worker to a contact status (shortlisted, contacted, interview_scheduled, selected, hired) for the first time.", "security": [ { "bearerAuth": [] } ], "parameters": [ { "name": "id", "in": "path", "required": true, "description": "The job application ID.", "schema": { "type": "integer" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "status" ], "properties": { "status": { "type": "string", "enum": [ "applied", "shortlisted", "contacted", "interview scheduled", "interview_scheduled", "selected", "rejected", "hired" ], "example": "shortlisted", "description": "The new status of the application." }, "notes": { "type": "string", "description": "Optional internal notes about the applicant/interview" } } } } } }, "responses": { "200": { "description": "Application status updated successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Application status updated successfully." }, "data": { "type": "object", "properties": { "application": { "type": "object", "properties": { "id": { "type": "integer", "example": 10 }, "worker_id": { "type": "integer", "example": 136 }, "job_id": { "type": "integer", "example": 1 }, "status": { "type": "string", "example": "shortlisted" }, "notes": { "type": "string", "example": "Scheduled phone screen for tomorrow.", "nullable": true }, "status_history": { "type": "array", "items": { "type": "object" } }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } } } } } } } } }, "401": { "description": "Unauthenticated or invalid Bearer token." }, "403": { "description": "Contact limit reached under the current subscription plan or unauthorized.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "You have reached your contacted workers limit of 10 under your active plan. Please upgrade or renew your subscription to contact more workers." } } } } } }, "404": { "description": "Job application not found or unauthorized access." }, "422": { "description": "Validation error (e.g. invalid status)." } } } }, "/workers/forgot-password": { "post": { "tags": [ "Workers - Auth" ], "summary": "Forgot Password (Send OTP)", "description": "Sends a 6-digit OTP to verify the worker's identity using their registered mobile number. Workers do not use email \u2014 mobile/phone is the primary identifier. OTP is valid for 10 minutes.", "operationId": "workerForgotPassword", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "phone" ], "properties": { "phone": { "type": "string", "example": "+971501234567", "description": "Worker's registered mobile number" } } } } } }, "responses": { "200": { "description": "OTP sent successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "If an account with that mobile number exists, a reset OTP has been sent." } } } } } }, "404": { "description": "Worker account not found with the provided mobile number.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "user not found this mobile number" } } } } } }, "422": { "description": "Validation error \u2014 phone is required" } } } }, "/workers/reset-password": { "post": { "tags": [ "Workers - Auth" ], "summary": "Reset Password (Verify OTP)", "description": "Verifies the OTP sent to the worker's mobile number and sets a new password. The phone number must match the one used in the forgot-password step.", "operationId": "workerResetPassword", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "phone", "otp", "password", "password_confirmation" ], "properties": { "phone": { "type": "string", "example": "+971501234567", "description": "Worker's registered mobile number" }, "otp": { "type": "string", "example": "482910", "description": "6-digit OTP received" }, "password": { "type": "string", "example": "newpassword123", "description": "New password (min 8 chars)" }, "password_confirmation": { "type": "string", "example": "newpassword123", "description": "Must match password" } } } } } }, "responses": { "200": { "description": "Password reset successfully" }, "422": { "description": "Invalid OTP, expired OTP, or validation error" }, "404": { "description": "Account not found" } } } }, "/employers/forgot-password": { "post": { "tags": [ "Employers - Auth" ], "summary": "Forgot Password (Send OTP)", "description": "Sends a 6-digit OTP to the employer's registered email address. OTP expires in 10 minutes.", "operationId": "employerForgotPassword", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "email" ], "properties": { "email": { "type": "string", "format": "email", "example": "employer@example.com" } } } } } }, "responses": { "200": { "description": "OTP sent (response identical whether account exists or not)" }, "422": { "description": "Validation error" } } } }, "/employers/reset-password": { "post": { "tags": [ "Employers - Auth" ], "summary": "Reset Password (Verify OTP)", "description": "Verifies the OTP sent to the employer's email and sets a new password.", "operationId": "employerResetPassword", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "email", "otp", "password", "password_confirmation" ], "properties": { "email": { "type": "string", "format": "email", "example": "employer@example.com" }, "otp": { "type": "string", "example": "482910" }, "password": { "type": "string", "example": "newpassword123" }, "password_confirmation": { "type": "string", "example": "newpassword123" } } } } } }, "responses": { "200": { "description": "Password reset successfully" }, "422": { "description": "Invalid or expired OTP" } } } }, "/sponsors/forgot-password": { "post": { "tags": [ "Sponsors - Auth" ], "summary": "Forgot Password (Send OTP)", "description": "Sends a 6-digit OTP to the sponsor's registered email. Accepts email or mobile number as identifier. OTP expires in 10 minutes.", "operationId": "sponsorForgotPassword", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "email": { "type": "string", "format": "email", "example": "sponsor@example.com", "description": "Email address (either email or mobile required)" }, "mobile": { "type": "string", "example": "+971501234567", "description": "Mobile number (either email or mobile required)" } } } } } }, "responses": { "200": { "description": "OTP sent successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "If an account with that contact exists, a reset OTP has been sent." } } } } } }, "404": { "description": "Sponsor account not found with the provided email or mobile.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "user not found this email id" } } } } } }, "422": { "description": "Validation error \u2014 email or mobile required" } } } }, "/sponsors/reset-password": { "post": { "tags": [ "Sponsors - Auth" ], "summary": "Reset Password (Verify OTP)", "description": "Verifies the OTP sent to the sponsor's email and sets a new password. Use the email field to identify the account.", "operationId": "sponsorResetPassword", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "email", "otp", "password", "password_confirmation" ], "properties": { "email": { "type": "string", "format": "email", "example": "sponsor@example.com" }, "otp": { "type": "string", "example": "482910" }, "password": { "type": "string", "example": "newpassword123" }, "password_confirmation": { "type": "string", "example": "newpassword123" } } } } } }, "responses": { "200": { "description": "Password reset successfully" }, "422": { "description": "Invalid or expired OTP" } } } }, "/employers/my-announcements": { "get": { "tags": [ "Employer/CharityEvents" ], "summary": "Get My Posted Announcements/Charity Events (Employer)", "description": "Retrieves the list of announcements and charity events posted specifically by the logged-in employer.", "parameters": [ { "name": "page", "in": "query", "required": false, "description": "Page number.", "schema": { "type": "integer", "default": 1 } }, { "name": "per_page", "in": "query", "required": false, "description": "Number of items per page.", "schema": { "type": "integer", "default": 15 } } ], "responses": { "200": { "description": "List of my posted announcements retrieved successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "announcements": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "example": 1 }, "title": { "type": "string", "example": "Holiday Notice" }, "body": { "type": "string", "example": "Office will be closed tomorrow." }, "type": { "type": "string", "example": "info" }, "status": { "type": "string", "example": "pending" }, "remarks": { "type": "string", "nullable": true }, "created_at": { "type": "string", "format": "date-time", "example": "2026-06-23T10:13:17.000000Z" }, "time_ago": { "type": "string", "example": "2 hours ago" } } } }, "pagination": { "type": "object", "properties": { "total": { "type": "integer", "example": 1 }, "per_page": { "type": "integer", "example": 15 }, "current_page": { "type": "integer", "example": 1 }, "last_page": { "type": "integer", "example": 1 } } } } } } } } } } } } }, "/workers/change-password": { "post": { "tags": [ "Worker/Profile" ], "summary": "Change Password", "description": "Securely changes the user's password by validating the current password and confirming the new password.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "current_password", "new_password", "new_password_confirmation" ], "properties": { "current_password": { "type": "string", "format": "password", "description": "The current login password. (REQUIRED)", "example": "OldPassword@123" }, "new_password": { "type": "string", "format": "password", "description": "The new secure password (minimum 8 characters). (REQUIRED)", "example": "NewPassword@123" }, "new_password_confirmation": { "type": "string", "format": "password", "description": "Confirmation of the new password. (REQUIRED)", "example": "NewPassword@123" } } } } } }, "responses": { "200": { "description": "Password changed successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Password changed successfully." } } } } } }, "422": { "description": "Validation error (e.g. invalid current password, password too short, or mismatch).", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "Validation error." }, "errors": { "type": "object", "properties": { "current_password": { "type": "array", "items": { "type": "string" }, "example": [ "The current password is incorrect." ] } } } } } } } } } } }, "/employers/change-password": { "post": { "tags": [ "Employer/Profile" ], "summary": "Change Password", "description": "Securely changes the user's password by validating the current password and confirming the new password.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "current_password", "new_password", "new_password_confirmation" ], "properties": { "current_password": { "type": "string", "format": "password", "description": "The current login password. (REQUIRED)", "example": "OldPassword@123" }, "new_password": { "type": "string", "format": "password", "description": "The new secure password (minimum 8 characters). (REQUIRED)", "example": "NewPassword@123" }, "new_password_confirmation": { "type": "string", "format": "password", "description": "Confirmation of the new password. (REQUIRED)", "example": "NewPassword@123" } } } } } }, "responses": { "200": { "description": "Password changed successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Password changed successfully." } } } } } }, "422": { "description": "Validation error (e.g. invalid current password, password too short, or mismatch).", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "Validation error." }, "errors": { "type": "object", "properties": { "current_password": { "type": "array", "items": { "type": "string" }, "example": [ "The current password is incorrect." ] } } } } } } } } } } }, "/sponsors/change-password": { "post": { "tags": [ "Sponsor" ], "summary": "Change Password", "description": "Securely changes the user's password by validating the current password and confirming the new password.", "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "required": [ "current_password", "new_password", "new_password_confirmation" ], "properties": { "current_password": { "type": "string", "format": "password", "description": "The current login password. (REQUIRED)", "example": "OldPassword@123" }, "new_password": { "type": "string", "format": "password", "description": "The new secure password (minimum 8 characters). (REQUIRED)", "example": "NewPassword@123" }, "new_password_confirmation": { "type": "string", "format": "password", "description": "Confirmation of the new password. (REQUIRED)", "example": "NewPassword@123" } } } } } }, "responses": { "200": { "description": "Password changed successfully.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "message": { "type": "string", "example": "Password changed successfully." } } } } } }, "422": { "description": "Validation error (e.g. invalid current password, password too short, or mismatch).", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": false }, "message": { "type": "string", "example": "Validation error." }, "errors": { "type": "object", "properties": { "current_password": { "type": "array", "items": { "type": "string" }, "example": [ "The current password is incorrect." ] } } } } } } } } } } }, "/workers/applied-jobs/{id}": { "get": { "tags": [ "Worker/Jobs" ], "summary": "Get Applied Job Details", "description": "Retrieves the detail, current status, and complete status history audit log of a worker's job application.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "The Job Application ID", "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Application details retrieved.", "content": { "application/json": { "schema": { "type": "object", "properties": { "success": { "type": "boolean", "example": true }, "data": { "type": "object", "properties": { "application": { "type": "object", "properties": { "id": { "type": "integer", "example": 12 }, "status": { "type": "string", "example": "shortlisted" }, "status_history": { "type": "array", "items": { "type": "object", "properties": { "status": { "type": "string" }, "timestamp": { "type": "string" }, "notes": { "type": "string", "nullable": true } } } } } } } } } } } } } } } }, "/workers/applied-jobs/{id}/withdraw": { "post": { "tags": [ "Worker/Jobs" ], "summary": "Withdraw Job Application", "description": "Allows a worker to withdraw their application. Only permitted if the application is still in 'applied' status.", "parameters": [ { "name": "id", "in": "path", "required": true, "description": "The Job Application ID", "schema": { "type": "integer" } } ], "responses": { "200": { "description": "Application successfully withdrawn." }, "400": { "description": "Cannot withdraw (status is not 'applied')." } } } } }, "components": { "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" } }, "schemas": { "Sponsor": { "type": "object", "properties": { "id": { "type": "integer", "example": 1 }, "full_name": { "type": "string", "example": "Mohammed Al-Rashidi" }, "organization_name": { "type": "string", "example": "Al-Rashidi Charitable Foundation" }, "email": { "type": "string", "example": "sponsor.971501112233@migrant.ae" }, "mobile": { "type": "string", "example": "+971501112233" }, "nationality": { "type": "string", "example": "UAE" }, "city": { "type": "string", "example": "Dubai" }, "address": { "type": "string", "example": "Villa 12, Jumeirah 2" }, "country_code": { "type": "string", "example": "+971" }, "is_verified": { "type": "boolean", "example": false }, "status": { "type": "string", "example": "active" }, "license_file": { "type": "string", "example": "uploads/licenses/1234567890_license_trade.pdf" }, "emirates_id_file": { "type": "string", "example": "uploads/licenses/1234567890_emirates_id.pdf" }, "license_expiry": { "type": "string", "nullable": true, "example": "2026-05-03" }, "validity": { "type": "string", "example": "Valid" }, "joined_at": { "type": "string", "format": "date-time" }, "fcm_token": { "type": "string", "example": "fcm_token_example" }, "license": { "type": "object", "properties": { "document_type": { "type": "string", "example": "dubai_commercial_license" }, "country": { "type": "string", "example": "United Arab Emirates" }, "authority": { "type": "string", "example": "Dubai Economy and Tourism" }, "license_no": { "type": "string", "example": "1426961" }, "company_name": { "type": "string", "example": "NEST CLIMATE TECHNICAL SERVICES L.L.C" }, "business_name": { "type": "string", "example": "NEST CLIMATE TECHNICAL SERVICES L.L.C" }, "license_category": { "type": "string", "example": "Dep. of Economic Development" }, "legal_type": { "type": "string", "example": "Limited Liability Company(LLC)" }, "issue_date": { "type": "string", "example": "22/10/2024" }, "expiry_date": { "type": "string", "example": "21/10/2026" }, "main_license_no": { "type": "string", "example": "1426961" }, "register_no": { "type": "string", "example": "2436760" }, "dcci_no": { "type": "string", "example": "570232" } } }, "emirates_id": { "type": "object", "properties": { "emirates_id_number": { "type": "string", "example": "784-1988-5310327-2" }, "name": { "type": "string", "example": "KRISHNA PRASAD" }, "date_of_birth": { "type": "string", "example": "1988-03-22" }, "issue_date": { "type": "string", "example": "2023-04-11" }, "expiry_date": { "type": "string", "example": "2028-04-11" }, "employer": { "type": "string", "example": "Federal Authority" }, "issue_place": { "type": "string", "example": "Abu Dhabi" }, "occupation": { "type": "string", "example": "Manager" }, "nationality": { "type": "string", "example": "NPL" }, "gender": { "type": "string", "example": "Male" } } }, "created_at": { "type": "string", "format": "date-time" } } }, "Worker": { "type": "object", "properties": { "id": { "type": "integer", "example": 136 }, "name": { "type": "string", "example": "Amina Al-Masry" }, "email": { "type": "string", "example": "worker.971509998888@migrant.com" }, "phone": { "type": "string", "example": "+971509998888" }, "language": { "type": "string", "example": "HI" }, "languages": { "type": "array", "items": { "type": "string" }, "example": [ "English", "Arabic" ] }, "fcm_token": { "type": "string", "example": "fcm_token_example" }, "nationality": { "type": "string", "example": "Egypt" }, "age": { "type": "integer", "example": 28 }, "salary": { "type": "string", "example": "1500.00" }, "availability": { "type": "string", "example": "Immediate" }, "experience": { "type": "string", "example": "4 Years" }, "bio": { "type": "string", "example": "Certified infant caregiver and housekeeper with excellent cooking skills." }, "verified": { "type": "boolean", "example": false }, "status": { "type": "string", "example": "active" }, "in_country": { "type": "boolean", "example": true }, "visa_status": { "type": "string", "example": "Tourist Visa" }, "passport_status": { "type": "string", "example": "Passport Verified" }, "emirates_id_status": { "type": "string", "example": "Passport Verified" }, "document_expiry_days": { "type": "integer", "example": -857 }, "document_expiry_status": { "type": "string", "example": "Visa Expired" }, "visa_expiry_date": { "type": "string", "format": "date", "example": "2024-02-15" }, "preferred_job_type": { "type": "string", "example": "full-time" }, "live_in_out": { "type": "string", "example": "Live-out" }, "gender": { "type": "string", "enum": [ "male", "female", "other" ], "example": "male" }, "preferred_location": { "type": "string", "example": "Dubai Marina" }, "country": { "type": "string", "example": "UAE" }, "city": { "type": "string", "example": "Dubai" }, "area": { "type": "string", "example": "Marina" }, "rating": { "type": "number", "example": 4.5 }, "reviews_count": { "type": "integer", "example": 2 }, "photo": { "type": "string", "nullable": true, "example": "https://example.com/photo.jpg" }, "created_at": { "type": "string", "format": "date-time", "example": "2026-05-20T14:54:26.000000Z" }, "updated_at": { "type": "string", "format": "date-time", "example": "2026-05-20T14:54:26.000000Z" }, "deleted_at": { "type": "string", "format": "date-time", "nullable": true, "example": null }, "category": { "type": "object", "properties": { "id": { "type": "integer", "example": 7 }, "name": { "type": "string", "example": "General Helper" } } }, "main_profession": { "type": "string", "nullable": true, "example": "Nanny", "description": "The main profession of the worker" }, "skills": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "integer", "example": 6 }, "name": { "type": "string", "example": "Cleaning" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" }, "image_path": { "type": "string", "nullable": true, "example": "skills/cleaning.png" }, "pivot": { "type": "object", "properties": { "worker_id": { "type": "integer", "example": 136 }, "skill_id": { "type": "integer", "example": 6 } } } } } }, "documents": { "type": "array", "items": { "$ref": "#/components/schemas/WorkerDocument" } } } }, "WorkerDocument": { "type": "object", "properties": { "id": { "type": "integer", "example": 15 }, "worker_id": { "type": "integer", "example": 136 }, "type": { "type": "string", "example": "passport" }, "number": { "type": "string", "example": "P345892" }, "issue_date": { "type": "string", "format": "date", "example": "2024-05-20" }, "expiry_date": { "type": "string", "format": "date", "example": "2034-05-20" }, "ocr_accuracy": { "type": "number", "example": 98.5 }, "file_path": { "type": "string", "nullable": true, "example": "uploads/documents/1716200000_passport_my_file.jpg" }, "ocr_data": { "type": "object", "nullable": true, "description": "OCR raw parsed data or confidence data" }, "created_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } }, "JobOffer": { "type": "object", "properties": { "id": { "type": "integer", "example": 1 }, "employer_id": { "type": "integer", "example": 2 }, "worker_id": { "type": "integer", "example": 136 }, "work_date": { "type": "string", "format": "date", "example": "2026-06-01" }, "location": { "type": "string", "example": "Dubai Marina, Silverene Towers" }, "salary": { "type": "string", "example": "2500.00" }, "notes": { "type": "string", "example": "Require housekeeping support starting from June 1st." }, "status": { "type": "string", "example": "pending" }, "created_at": { "type": "string", "format": "date-time", "example": "2026-05-20T15:23:44.000000Z" }, "updated_at": { "type": "string", "format": "date-time", "example": "2026-05-20T15:23:44.000000Z" } } } } } }