migrant-web/public/swagger.json
2026-06-14 00:05:05 +05:30

4780 lines
224 KiB
JSON

{
"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 — dashboard and charity events only. No payment required.",
"security": [],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"required": [
"full_name",
"mobile",
"password",
"license_file",
"emirates_id_file",
"organization_name",
"email",
"nationality",
"city",
"address",
"country_code",
"license_expiry"
],
"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 — must be unique. (REQUIRED)"
},
"password": {
"type": "string",
"format": "password",
"example": "securepass123",
"description": "Login password (min 6 characters). (REQUIRED)"
},
"license_file": {
"type": "string",
"format": "binary",
"description": "Organization or trade license document (jpg/png/pdf, max 10MB). (REQUIRED)"
},
"emirates_id_file": {
"type": "string",
"format": "binary",
"description": "Emirates ID document file (jpg/png/pdf, max 10MB). (REQUIRED)"
},
"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)"
}
}
}
}
}
},
"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/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"
}
}
}
}
}
},
"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."},
"401": {"description": "Unauthenticated."}
}
}
},
"/workers/register": {
"post": {
"tags": [
"Worker/Auth"
],
"summary": "Register Worker & Upload Documents (Unified API)",
"description": "Performs worker registration and uploads their passport/visa documents in a single, robust multipart form request. Generates and returns a secure stateless bearer token upon success. Password is required (min 6 characters).",
"security": [],
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"required": [
"name",
"phone",
"salary",
"password",
"passport_file"
],
"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)"
},
"passport_file": {
"type": "string",
"format": "binary",
"description": "Physical scan or image of the Passport (Max 10MB). (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)."
},
"visa_file": {
"type": "string",
"format": "binary",
"description": "Optional physical scan or image of the Visa (Max 10MB)."
},
"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."
},
"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."
}
}
}
}
}
},
"responses": {
"201": {
"description": "Worker registered and authenticated successfully.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Worker registered and authenticated successfully."
},
"data": {
"type": "object",
"properties": {
"worker": {
"$ref": "#/components/schemas/Worker"
},
"token": {
"type": "string",
"example": "abc123xyz456...secureToken..."
}
}
}
}
}
}
}
},
"422": {
"description": "Validation error details.",
"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."
]
}
}
}
}
}
}
}
}
}
}
},
"/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."
}
}
}
}
}
},
"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/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 (हिन्दी)"
}
}
}
}
}
}
}
}
}
}
}
},
"/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": "India"
},
"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."
}
}
}
}
}
},
"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 age, nationality, desired salary, bio, availability, experience, religion, categories, and master skills list.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"example": "Amina Al-Masry"
},
"age": {
"type": "integer",
"example": 28
},
"nationality": {
"type": "string",
"example": "Egypt"
},
"salary": {
"type": "number",
"example": 1800
},
"availability": {
"type": "string",
"example": "Immediate"
},
"experience": {
"type": "string",
"example": "4 Years"
},
"religion": {
"type": "string",
"example": "Muslim"
},
"bio": {
"type": "string",
"example": "Highly certified housekeeper and babysitter with cooking experience."
},
"category_id": {
"type": "integer",
"example": 8
},
"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."
}
}
}
}
}
},
"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/profile/upload-emirates-id": {
"post": {
"tags": [
"Worker/Profile"
],
"summary": "Upload Emirates ID scan & Secure OCR Extract & Purge physical image (PDPL compliant)",
"description": "Accepts an Emirates ID scan file, performs automatic OCR extraction of card fields (Name, ID, Expiry), instantly purges/deletes the physical file image from servers to comply with PDPL privacy regulations, and awards the Verified Badge to the worker.",
"requestBody": {
"required": true,
"content": {
"multipart/form-data": {
"schema": {
"type": "object",
"required": [
"emirates_id_file"
],
"properties": {
"emirates_id_file": {
"type": "string",
"format": "binary",
"description": "Physical scan or image file of the Emirates ID (Max 10MB)."
}
}
}
}
}
},
"responses": {
"200": {
"description": "Emirates ID verified and physical file safely purged.",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean",
"example": true
},
"message": {
"type": "string",
"example": "Emirates ID verified successfully. Your verified badge is now active. Physical file purged for PDPL compliance."
},
"ocr_extracted_data": {
"type": "object",
"properties": {
"name": {
"type": "string",
"example": "Rahul Sharma"
},
"emirates_id_number": {
"type": "string",
"example": "784-1995-1234567-1"
},
"expiry_date": {
"type": "string",
"example": "2029-05-25"
}
}
}
}
}
}
}
}
}
}
},
"/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 Review).",
"parameters": [
{
"name": "type",
"in": "query",
"required": false,
"description": "Optional type to filter reasons (Chat or Review). If not provided, returns all active reasons.",
"schema": {
"type": "string",
"enum": [
"Chat",
"Review"
]
}
}
],
"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": {
"application/json": {
"schema": {
"type": "object",
"required": [
"message"
],
"properties": {
"message": {
"type": "string",
"example": "I tried clearing cache and it still crashes."
}
}
}
}
}
},
"responses": {
"201": {
"description": "Reply posted successfully."
}
}
}
},
"/employers/register": {
"post": {
"tags": [
"Employer/Auth"
],
"summary": "Register Sponsor (Alias)",
"description": "Legacy route matching the simplified sponsor registration (Name, Email, Phone).",
"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"
}
}
}
}
}
},
"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"
}
}
}
}
}
},
"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 3).",
"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 4). 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"
}
}
}
}
}
},
"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"
}
}
}
}
}
},
"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/forgot-password": {
"post": {
"tags": [
"Employer/Auth"
],
"summary": "Request Password Reset Code",
"description": "Validates employer email and sends a 6-digit password reset verification code (OTP).",
"security": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"email"
],
"properties": {
"email": {
"type": "string",
"example": "ahmad@example.com"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Password reset verification code sent successfully."
},
"404": {
"description": "No employer account found with this email."
}
}
}
},
"/employers/reset-password": {
"post": {
"tags": [
"Employer/Auth"
],
"summary": "Reset Password with Verification Code",
"description": "Verifies the 6-digit OTP code and updates the password for both employer user and sponsor records.",
"security": [],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"email",
"otp",
"password",
"password_confirmation"
],
"properties": {
"email": {
"type": "string",
"example": "ahmad@example.com"
},
"otp": {
"type": "string",
"example": "111111"
},
"password": {
"type": "string",
"example": "SecureNewPassword@123"
},
"password_confirmation": {
"type": "string",
"example": "SecureNewPassword@123"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Password reset successfully."
},
"400": {
"description": "Invalid or expired verification code."
}
}
}
},
"/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."
}
}
}
},
"/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."
}
}
},
"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."
}
}
}
},
"/employers/profile": {
"get": {
"tags": [
"Employer/Profile"
],
"summary": "Get Profile details (Employer)",
"description": "Retrieves the authenticated employer's profile details including their selected company name, phone, language preference, and notification settings.",
"responses": {
"200": {
"description": "Employer profile details retrieved successfully."
}
}
}
},
"/employers/profile/update": {
"post": {
"tags": [
"Employer/Profile"
],
"summary": "Update Profile details (Employer)",
"description": "Allows employers to update their profile details (company name, phone number, name, email, language preference, and notification settings) and change their account password.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"name",
"email",
"phone",
"company_name",
"language",
"notifications"
],
"properties": {
"name": {
"type": "string",
"example": "Ahmad"
},
"email": {
"type": "string",
"example": "ahmad@example.com"
},
"phone": {
"type": "string",
"example": "+971509990001"
},
"company_name": {
"type": "string",
"example": "Ahmad Tech Ltd"
},
"language": {
"type": "string",
"enum": [
"English",
"Arabic",
"english",
"arabic"
],
"example": "English"
},
"notifications": {
"type": "boolean",
"example": true
},
"current_password": {
"type": "string",
"example": "Password@123"
},
"new_password": {
"type": "string",
"example": "NewSecurePassword@123"
},
"new_password_confirmation": {
"type": "string",
"example": "NewSecurePassword@123"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Profile updated successfully."
}
}
}
},
"/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. India,Kenya,Ethiopia).",
"schema": {
"type": "string"
}
},
{
"name": "gender",
"in": "query",
"required": false,
"description": "Filter by gender (e.g. male, female).",
"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."
}
}
}
},
"/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": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"example": 1
},
"name": {
"type": "string",
"example": "Jane Doe"
},
"nationality": {
"type": "string",
"example": "Filipino"
},
"photo": {
"type": "string",
"example": "https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?auto=format&fit=crop&q=80&w=200"
},
"emirates_id_status": {
"type": "string",
"example": "Passport Verified",
"description": "Deprecated - Use passport_status instead"
},
"passport_status": {
"type": "string",
"example": "Passport Verified"
},
"category": {
"type": "string",
"example": "Domestic Worker"
},
"skills": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"childcare",
"cooking"
]
},
"availability_status": {
"type": "string",
"example": "Active"
},
"visa_status": {
"type": "string",
"example": "Residence Visa"
},
"experience": {
"type": "string",
"example": "5 Years"
},
"experience_years": {
"type": "integer",
"example": 5
},
"salary": {
"type": "integer",
"example": 2500
},
"religion": {
"type": "string",
"example": "Christian"
},
"languages": {
"type": "array",
"items": {
"type": "string"
},
"example": [
"English",
"Tagalog"
]
},
"age": {
"type": "integer",
"example": 28
},
"verified": {
"type": "boolean",
"example": true
},
"preferred_job_type": {
"type": "string",
"example": "live-in"
},
"bio": {
"type": "string",
"example": "Experienced and caring domestic worker specialing in childcare and housekeeping..."
},
"rating": {
"type": "number",
"example": 4.3
},
"reviews_count": {
"type": "integer",
"example": 6
},
"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. India,Kenya,Ethiopia).",
"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 Review).",
"parameters": [
{
"name": "type",
"in": "query",
"required": false,
"description": "Optional type to filter reasons (Chat or Review). If not provided, returns all active reasons.",
"schema": {
"type": "string",
"enum": [
"Chat",
"Review"
]
}
}
],
"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": {
"application/json": {
"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"
}
}
}
}
}
},
"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": {
"application/json": {
"schema": {
"type": "object",
"required": [
"message"
],
"properties": {
"message": {
"type": "string",
"example": "I tried a different card and it still fails."
}
}
}
}
}
},
"responses": {
"201": {
"description": "Reply posted successfully."
}
}
}
}
},
"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"},
"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"
},
"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"
},
"religion": {
"type": "string",
"example": "Muslim"
},
"bio": {
"type": "string",
"example": "Certified infant caregiver and housekeeper with excellent cooking skills."
},
"category_id": {
"type": "integer",
"example": 7
},
"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"
},
"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"
},
"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"
},
"category": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"example": 7
},
"name": {
"type": "string",
"example": "General Helper"
}
}
},
"skills": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"example": 6
},
"name": {
"type": "string",
"example": "Cleaning"
}
}
}
},
"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",
"example": "uploads/documents/1716200000_passport_my_file.jpg"
}
}
},
"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"
}
}
}
}
}
}