# Ad Creation — Field Reference

> **Endpoints:**
> - `POST /v1/client/ads/cars`
> - `POST /v1/client/ads/plates`
> - `POST /v1/client/ads/real-estate`
> - `POST /v1/client/ads/business`
>
> **Note:** Ads are create-only. There is no update endpoint.

---

## 1. Cars — `POST /v1/client/ads/cars`

**Supported `ad_type` values:** `sell` — `exchange`

### Base Fields

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `ad_type` | string | Required | `sell` — `exchange` |
| `name` | string | Required | max 255 chars |
| `description` | string | Optional | max 2000 chars |
| `city_id` | integer | Required | Active city ID |
| `district_id` | integer | Required | Active district ID |
| `data_accuracy_confirmed` | boolean | Required | Must be `true` |

### Car Details

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `brand_id` | integer | Required | ID from brands list |
| `model_id` | integer | Required | ID from models list, filtered by brand |
| `manufacture_year` | integer | Required | 1990 – current year |
| `kilometers` | integer | Required | min 0 |
| `car_status` | string | Required | `new` — `used` |
| `transmission` | string | Required | `manual` — `automatic` |
| `body_condition` | string | Required | `agency` — `cosmetic_paint` — `accident_paint` — `damaged` |
| `engine_condition` | string | Required | `excellent` — `good` — `needs_maintenance` — `needs_restoration` |
| `fuel_type` | string | Required | `petrol` — `diesel` — `hybrid` — `electric` |
| `inspection_date` | date | Optional | Format: Y-m-d |
| `inspection_file` | integer | Optional | Media ID — PDF inspection file |

### Sell Fields

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `final_price` | numeric | Required if `ad_type = sell` | min 0, in SAR |
| `includes_transfer_fees` | boolean | Required if `ad_type = sell` | `true` — `false` |

### Exchange Fields

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `exchange_for` | integer | Required if `ad_type = exchange` | Category ID — what the owner accepts in return |
| `required_description` | string | Required if `ad_type = exchange` | Description of what is needed, max 2000 chars |
| `price_difference_type` | string | Required if `ad_type = exchange` | `i_pay` — `i_request` — `even` |
| `max_difference_amount` | numeric | Optional | Max acceptable price difference in SAR |

### Media

| Field | Type | Status | Notes |
|-------|------|--------|-------|
| `cover_image` | integer | Required | Media ID — main display image |
| `images` | array of integers | Optional | Media IDs — additional gallery images, max 19 |

---

## 2. Plates — `POST /v1/client/ads/plates`

**Supported `ad_type` values:** `sell` — `exchange`

### Base Fields

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `ad_type` | string | Required | `sell` — `exchange` |
| `name` | string | Required | max 255 chars |
| `description` | string | Optional | max 2000 chars |
| `city_id` | integer | Required | Active city ID |
| `district_id` | integer | Required | Active district ID |
| `data_accuracy_confirmed` | boolean | Required | Must be `true` |

### Plate Details

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `plate_type` | string | Required | `private` — `private_transport` — `public_transport` — `motorcycle` |
| `arabic_numbers` | string | Required | Arabic plate numbers, max 10 chars |
| `ready_for_transfer_ownership` | boolean | Required | `true` — `false` |
| `arabic_chars` | string | Optional | Arabic letters on plate, max 4 chars |
| `english_chars` | string | Optional | English letters on plate, max 4 chars |
| `english_numbers` | string | Optional | English plate numbers, max 10 chars |
| `plate_distinction_id` | integer | Optional | ID from plate distinctions list |

### Sell Fields

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `final_price` | numeric | Required if `ad_type = sell` | min 0, in SAR |
| `includes_transfer_fees` | boolean | Required if `ad_type = sell` | `true` — `false` |

### Exchange Fields

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `exchange_for` | integer | Required if `ad_type = exchange` | Category ID |
| `price_difference_type` | string | Required if `ad_type = exchange` | `i_pay` — `i_request` — `even` |
| `required_description` | string | Optional | Description of what is needed, max 2000 chars |
| `max_difference_amount` | numeric | Optional | Max acceptable price difference in SAR |

### Media

| Field | Type | Status | Notes |
|-------|------|--------|-------|
| `cover_image` | integer | Required | Media ID — main display image |
| `images` | array of integers | Optional | Media IDs — additional gallery images, max 19 |

---

## 3. Real Estate — `POST /v1/client/ads/real-estate` — `PUT /v1/client/ads/real-estate/{id}`

**Supported `ad_type` values:** `sell` — `exchange` — `partner`

> **Update note:** All fields are `sometimes|required` on PUT/PATCH — only send what you want to change. `cover_image` and `images` are optional on update.

### 1. غرض الإعلان

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `ad_type` | string | Required | `sell` — `exchange` — `partner` |

### 2. صفة المعلن

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `advertiser_role` | string | Required | `owner` — `broker` — `real_estate_company` |

### 3. بيانات المعلن والتراخيص

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `owner_id_number` | string | Required | National ID — exactly 10 digits |
| `birth_date` | date | Required | Format: Y-m-d — advertiser must be at least 18 years old |
| `phone` | string | Required | max 20 chars — pre-filled from account data |
| `ad_license_number` | string | Required | Real estate ad license number, max 50 chars |
| `ad_license_url` | string | Required | Full URL to license document, max 500 chars |
| `license_issue_date` | date | Required | Format: Y-m-d |
| `license_expiry_date` | date | Required | Format: Y-m-d — must be on or after issue date |
| `fal_number` | string | Required if `advertiser_role = broker` | FAL license number, max 50 chars |
| `brokerage_file` | integer | Required if `advertiser_role = broker` | Media ID — brokerage license file |
| `has_commission` | boolean | Required if `advertiser_role = broker` | `true` — `false` |
| `commission_value` | string | Required if `advertiser_role = broker` AND `has_commission = true` | Commission amount or percentage, max 100 chars |
| `unified_number` | string | Required if `advertiser_role = real_estate_company` | Unified entity number, max 50 chars |
| `commercial_register` | integer | Required if `advertiser_role = real_estate_company` | Media ID — commercial registration file |

### 4. الموقع

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `region_id` | integer | Required | Active region ID |
| `city_id` | integer | Required | Active city ID — must belong to `region_id` |
| `district_id` | integer | Required | Active district ID — must belong to `city_id` |

### 5. نوع العقار

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `property_type` | string | Required | Values from `PropertyTypeEnum` |

### 6. البيانات القانونية للعقار

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `deed_number` | string | Required | Deed / property / registry number, max 50 chars |
| `has_mortgage` | boolean | Required | `true` — `false` |
| `mortgage_details` | string | Required if `has_mortgage = true` | Details of mortgage or encumbrance, max 2000 chars |
| `obligations` | string | Required | Rights and obligations, max 2000 chars |
| `has_legal_dispute` | boolean | Required | `true` — `false` |
| `legal_dispute_details` | string | Required if `has_legal_dispute = true` | Details of legal disputes, max 2000 chars |

### 7. بيانات المبنى

> Used when `property_type` resolves to a **building** group (e.g. villa, apartment, complex, chalet, commercial).  
> Building-only fields are rejected for land types.

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `building_type_id` | integer | Required if building | Active building type ID — load from `GET /general/building-types` |
| `purpose` | string | Required | `residential` — `commercial` — `residential_commercial` (سكني / تجاري / تجاري سكني) |
| `area_m2` | numeric | Required if building type | Area in m², min 1, max 99,999,999 |
| `rooms` | integer | Optional | Number of rooms, min 0, max 999 |
| `bathrooms` | integer | Optional | Number of bathrooms, min 0, max 999 |
| `floor` | integer | Optional | Floor number, min 0, max 999 |
| `floors_count` | integer | Optional | Total floors in building, min 0, max 999 |
| `property_age` | integer | Optional | Age in years, min 0, max 999 |
| `facade` | string | Optional | `north` — `south` — `east` — `west` — `multiple` |
| `utilities` | array of strings | Optional | `electricity` — `water` — `sewage` — `internet` |
| `building_description` | string | Optional | Additional building details, max 3000 chars |

### 8. بيانات الأرض

> Used when `property_type` resolves to a **land** group.  
> Land-only fields are rejected for building types.

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `area_m2` | numeric | Required if land type | Area in m², min 1, max 99,999,999 |
| `purpose` | string | Required | `residential` — `commercial` — `residential_commercial` (سكني / تجاري / تجاري سكني) |
| `land_plan_number` | string | Optional | Plan number, max 100 chars |
| `land_piece_number` | string | Optional | Piece/plot number, max 100 chars |
| `land_facade` | string | Optional | `north` — `south` — `east` — `west` — `multiple` |
| `land_facade_length` | numeric | Optional | Facade length in meters, min 0, max 99,999 |
| `street_width` | numeric | Optional | Street width in meters, min 0, max 9999 |
| `streets_count` | integer | Optional | Number of surrounding streets, min 0, max 99 |
| `land_description` | string | Optional | Additional land details, max 3000 chars |

### 9. بيانات غرض الإعلان

#### في حالة البيع (`ad_type = sell`)

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `final_price` | numeric | Required if `ad_type = sell` AND `property_type = building` | min 0, in SAR. Do **not** send for land. |
| `price_per_meter` | numeric | Required if `ad_type = sell` AND `property_type = land` | Price per m² in SAR. Do **not** send for buildings. |
| `vacancy_readiness` | string | Required if `ad_type = sell` | Values from `VacancyReadinessEnum` |

> `final_price` and `price_per_meter` are mutually exclusive — only one applies depending on `property_type`.

#### في حالة البدل (`ad_type = exchange`)

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `exchange_for` | integer | Required if `ad_type = exchange` | Category ID of accepted asset |
| `required_description` | string | Required if `ad_type = exchange` | Description of required asset, max 2000 chars |
| `price_difference_type` | string | Required if `ad_type = exchange` | `i_pay` — `i_request` — `even` |
| `max_difference_amount` | numeric | Required if `price_difference_type` is `i_pay` or `i_request` | Max price difference in SAR |

#### في حالة إضافة شريك (`ad_type = partner`)

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `partnership_type` | string | Required if `ad_type = partner` | `build_and_sell` — `build_and_rent` — `long_term_investment` |
| `partner_description` | string | Required if `ad_type = partner` | Partnership opportunity description, max 3000 chars |
| `required_amount` | numeric | Required if `ad_type = partner` | Required investment amount in SAR |
| `offered_share_percentage` | numeric | Required if `ad_type = partner` | Offered equity share, 0 to 100 |

### الإقرار بصحة البيانات

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `data_accuracy_confirmed` | boolean | Required | Must be `true` (accepted) |

### 10. الصور

| Field | Type | Status | Notes |
|-------|------|--------|-------|
| `cover_image` | integer | Required | Media ID — main display image |
| `images` | array of integers | Required | Media IDs — min 1, max 15 |



---

## 4. Business — `POST /v1/client/ads/business`

**Supported `ad_type` values:** `sell` — `exchange` — `partner`

### Base Fields

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `ad_type` | string | Required | `sell` — `exchange` — `partner` |
| `name` | string | Required | max 255 chars |
| `description` | string | Optional | max 2000 chars |
| `city_id` | integer | Required | Active city ID |
| `district_id` | integer | Required | Active district ID |
| `data_accuracy_confirmed` | boolean | Required | Must be `true` |

### Business Details

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `business_activity_type_id` | integer | Required | ID from business activity types list |
| `ownership_nature` | string | Required | `rent` — `owned` — `equipment_liquidation` |
| `operation_status` | string | Required | `active` — `under_establishment` — `struggling` |
| `brand_included` | string | Required | `included` — `not_included` |
| `licenses_status` | string | Required | `valid` — `expired` — `needs_transfer` |
| `id_number` | string | Required | National ID or Commercial Registration — exactly 10 digits |

### Sell Fields

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `final_price` | numeric | Required if `ad_type = sell` | min 0, in SAR |
| `financial_obligations` | numeric | Optional | Debts and obligations amount in SAR |

### Exchange Fields

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `exchange_for` | integer | Required if `ad_type = exchange` | Category ID |
| `required_description` | string | Required if `ad_type = exchange` | max 2000 chars |
| `price_difference_type` | string | Required if `ad_type = exchange` | `i_pay` — `i_request` — `even` |
| `max_difference_amount` | numeric | Optional | Max acceptable price difference in SAR |

### Partner Fields

| Field | Type | Status | Allowed Values / Notes |
|-------|------|--------|------------------------|
| `partnership_type` | string | Required if `ad_type = partner` | `build_and_sell` — `build_and_rent` — `long_term_investment` (نوع الشراكة) |
| `partner_type` | string | Required if `ad_type = partner` | `financier` — `operator` — `technical` — `effort_partner` (نوع الشريك) |
| `offered_share_percentage` | numeric | Required if `ad_type = partner` | 0 to 100 |
| `required_amount` | numeric | Required if `ad_type = partner` | Investment amount in SAR |

### Media

| Field | Type | Status | Notes |
|-------|------|--------|-------|
| `cover_image` | integer | Required | Media ID — main display image |
| `images` | array of integers | Optional | Media IDs — additional gallery images, max 19 |
| `inspection_file` | integer | Optional | Media ID — business inspection document (PDF) |

---

## Media Upload Flow

Upload all images and files before creating the ad. All media fields expect an integer ID returned from the upload endpoint.

1. Upload the file via the media upload endpoint
2. Receive a media `id` integer in the response
3. Pass that `id` in the ad creation request fields

---

## Lookup Endpoints for Dropdowns

| Data | Endpoint | Notes |
|------|----------|-------|
| Cities | `GET /general/cities` | Active only |
| Districts | `GET /general/districts` | Active only — supports `?city_id=` filter |
| Car brands | `GET /general/brands` | All brands |
| Car models | `GET /general/car-models` | Supports `?brand_id=` filter |
| Plate distinctions | `GET /general/plate-distinctions` | Active only |
| Business activity types | `GET /general/business-activity-types` | Active only |
| Building types | `GET /general/building-types` | Active only — used for `building_type_id` |
| Categories (for `exchange_for`) | `GET /general/categories` | Active only |

---

## Form Step Logic

```
Step 1 — Select ad_type
         sell / exchange / partner
         This determines which conditional section to show

Step 2 — Fill base fields
         name, city_id, district_id, description

Step 3 — Fill category-specific fields

         Cars:
           brand_id, model_id, manufacture_year, kilometers,
           car_status, transmission, body_condition, engine_condition, fuel_type

         Plates:
           plate_type, arabic_numbers, ready_for_transfer_ownership,
           arabic_chars, english_chars, english_numbers, plate_distinction_id

         Real Estate:
           advertiser_role, owner_id_number, birth_date, phone (required)
           if advertiser_role = broker:
             fal_number, brokerage_file, has_commission
             commission_value (required if has_commission = true)
           if advertiser_role = real_estate_company:
             unified_number, commercial_register
           ad_license_number, ad_license_url, license_issue_date, license_expiry_date
           region_id, city_id, district_id
           property_type
           deed_number (required), has_mortgage (required), obligations (required),
           has_legal_dispute (required)
           mortgage_details (required if has_mortgage = true)
           legal_dispute_details (required if has_legal_dispute = true)
           if property_type resolves to land group:
             area_m2 (required), purpose, land_plan_number, land_piece_number,
             land_facade, land_facade_length, street_width, streets_count, land_description
           if property_type resolves to building group:
             building_type_id (required), purpose, area_m2 (required), rooms, bathrooms, floor,
             floors_count, property_age, facade, utilities, building_description

         Business:
           business_activity_type_id, ownership_nature, operation_status,
           brand_included, licenses_status

Step 4 — Fill ad_type-specific fields

         sell:
           Cars and Plates: final_price (required), includes_transfer_fees
           Real Estate (building): final_price (required), vacancy_readiness
           Real Estate (land): price_per_meter (required), vacancy_readiness
           Business: final_price (required), financial_obligations (optional)

         exchange:
           exchange_for, required_description, price_difference_type
           max_difference_amount (optional)

         partner:
           Real Estate: partnership_type, partner_description, offered_share_percentage, required_amount
           Business: partnership_type (نوع الشراكة), partner_type (نوع الشريك),
                     offered_share_percentage, required_amount

Step 5 — Upload and attach media

         All categories:
           cover_image (required)
           images[] (optional, max 19)

         Cars only:
           inspection_file (optional PDF)

         Business only:
           inspection_file (optional PDF)

Step 6 — Set data_accuracy_confirmed = true

Step 7 — Submit
```
