# Contacts API

Manage people and organizations involved in property management — real estate agents, contractors, insurance agents, legal advisors, and other professional contacts. For tenants use [Lessees](/people/lessees), for property owners use [Owners](/people/owners).

## Quick Example

```bash
curl -X POST https://api.faireplace.com/api/contacts \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type_contact": "Company",
    "legal_name": "Cabinet Durand & Associes",
    "email": "contact@cabinet-durand.fr",
    "mobile": "+33145678901",
    "category": "Legal Advisor",
    "address_line1": "42 boulevard Haussmann",
    "address_city": "Paris",
    "address_postal_code": "75009",
    "address_country": "France"
  }'
```

## Common Workflows

### Add a property management company
1. `POST /api/contacts` — Create with `type_contact: "Company"` and `category: "Property Manager"`
2. Add professional card details (carte professionnelle) for regulatory compliance
3. `GET /api/contacts/{id}/entities` — View associated properties and leases

### Find contacts by role
1. `GET /api/contacts/roles` — List available roles
2. `GET /api/contacts/category/Maintenance` — Get all maintenance contacts
3. `GET /api/contacts?search=dupont&city=Paris` — Search with filters

---

## Overview

The Contacts API provides comprehensive contact management with support for:
- **Personal and Business Contacts**: Both individual and company contacts
- **Professional Information**: Special fields for property management professionals
- **Banking Details**: IBAN, SWIFT codes for payment processing
- **Address Management**: Complete address information
- **Contact Categorization**: Flexible categorization and search capabilities

## Authentication

All endpoints require authentication with the following permissions:
- **PropertiesRead**: For GET operations
- **PropertiesWrite**: For POST and PUT operations  
- **PropertiesDelete**: For DELETE operations

## Base URL

All contact endpoints are prefixed with `/api/contacts`

---

## Core Contact Operations

### List Contacts
**GET** `/api/contacts`

Retrieve all contacts with optional pagination and filtering.

**Query Parameters:**
- `page` (integer, optional): Page number (default: 1)
- `per_page` (integer, optional): Items per page (default: 10)
- `sort_by` (string, optional): Sort field (default: "created_at")
- `sort_order` (string, optional): "asc" or "desc" (default: "desc")
- `type_contact` (string, optional): Filter by contact type
- `category` (string, optional): Filter by category
- `search_term` (string, optional): Search across name and email fields
- `city` (string, optional): Filter by city
- `country` (string, optional): Filter by country

**Response:**
```json
[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "type_contact": "Individual",
    "first_name": "Jean",
    "last_name": "Dupont",
    "legal_name": null,
    "registration_number": null,
    "email": "jean.dupont@example.com",
    "mobile": "+33612345678",
    "telephone": "+33123456789",
    "website": "https://www.jean-dupont.fr",
    "color": "#3498db",
    "category": "Tenant",
    "address_line1": "123 Rue de la Paix",
    "address_line2": "Appartement 4B",
    "address_city": "Paris",
    "address_postal_code": "75001",
    "address_region": "Île-de-France",
    "address_country": "France",
    "bank_name": "Crédit Agricole",
    "bank_address": "456 Boulevard Saint-Germain",
    "bank_city": "Paris",
    "bank_postal_code": "75007",
    "bank_country": "France",
    "iban": "FR1420041010050500013M02606",
    "swift_bic": "AGRIFRPP",
    "bank_account_holder": "Jean Dupont",
    "professional_activity": null,
    "professional_card_number": null,
    "professional_card_issuing_location": null,
    "professional_card_issuing_date": null,
    "professional_card_expiry_date": null,
    "professional_registration_number": null,
    "professional_guarantor_id": null,
    "professional_insurance_company": null,
    "professional_insurance_policy": null,
    "professional_status": null,
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T10:30:00Z"
  }
]
```

### Create Contact
**POST** `/api/contacts`

Create a new contact.

**Request Body:**
```json
{
  "type_contact": "Individual",
  "first_name": "Marie",
  "last_name": "Martin",
  "email": "marie.martin@example.com",
  "mobile": "+33698765432",
  "telephone": "+33187654321",
  "website": "https://www.marie-martin.fr",
  "color": "#e74c3c",
  "category": "Owner",
  "address_line1": "789 Avenue des Champs-Élysées",
  "address_line2": "Étage 3",
  "address_city": "Paris",
  "address_postal_code": "75008",
  "address_region": "Île-de-France",
  "address_country": "France",
  "bank_name": "BNP Paribas",
  "iban": "FR1430002005500000157841Z25",
  "swift_bic": "BNPAFRPP",
  "bank_account_holder": "Marie Martin"
}
```

**Response:** `201 Created`
Returns the created contact object with generated ID and timestamps.

### Get Contact
**GET** `/api/contacts/{id}`

Retrieve a specific contact by ID.

**Path Parameters:**
- `id` (UUID): The contact ID

**Response:** `200 OK`
Returns the contact object.

### Update Contact
**PUT** `/api/contacts/{id}`

Update an existing contact. All fields are optional in update requests.

**Path Parameters:**
- `id` (UUID): The contact ID

**Request Body:**
```json
{
  "email": "marie.martin.updated@example.com",
  "mobile": "+33612345678",
  "color": "#9b59b6"
}
```

**Response:** `200 OK`
Returns the updated contact object.

### Delete Contact
**DELETE** `/api/contacts/{id}`

Delete a contact.

**Path Parameters:**
- `id` (UUID): The contact ID

**Response:** `204 No Content`

---

## Contact Search and Filtering

### Search Contacts
**GET** `/api/contacts/search`

Advanced contact search with multiple criteria.

**Query Parameters:**
- All parameters from the list endpoint
- `created_after` (ISO 8601 date): Filter contacts created after date
- `created_before` (ISO 8601 date): Filter contacts created before date

**Response:** `200 OK`
Returns paginated search results.

### Filter Contacts
**POST** `/api/contacts/filter`

Filter contacts using a POST request for complex criteria.

**Request Body:**
```json
{
  "type_contact": "Individual",
  "category": "Tenant",
  "search_term": "jean",
  "city": "Paris",
  "country": "France"
}
```

**Response:** `200 OK`
Returns filtered contact list.

### Get Contacts by Category
**GET** `/api/contacts/category/{category}`

Retrieve contacts by specific category.

**Path Parameters:**
- `category` (string): The contact category

**Response:** `200 OK`
Returns contacts in the specified category.

### Get Contacts by Type
**GET** `/api/contacts/type/{type}`

Retrieve contacts by contact type.

**Path Parameters:**
- `type` (string): The contact type (Individual, Company)

**Response:** `200 OK`
Returns contacts of the specified type.

---

## Professional Contact Management

### Get Contact Roles
**GET** `/api/contacts/roles`

Retrieve all available contact roles in the system.

**Response:** `200 OK`
```json
[
  {
    "role": "Property Manager"
  },
  {
    "role": "Tenant"
  },
  {
    "role": "Owner"
  },
  {
    "role": "Maintenance"
  },
  {
    "role": "Legal Advisor"
  }
]
```

### Get Contacts by Role
**GET** `/api/contacts/{id}/role/{role}`

Retrieve contacts that have a specific role.

**Path Parameters:**
- `id` (UUID): The contact ID
- `role` (string): The role name

**Response:** `200 OK`
Returns contacts with the specified role.

### Get Contact Entities
**GET** `/api/contacts/{id}/entities`

Retrieve all entities (properties, leases) associated with a contact.

**Path Parameters:**
- `id` (UUID): The contact ID

**Response:** `200 OK`
```json
{
  "contact_id": "550e8400-e29b-41d4-a716-446655440000",
  "properties": [
    {
      "id": "property-uuid",
      "name": "Apartment Complex A",
      "role": "Owner"
    }
  ],
  "leases": [
    {
      "id": "lease-uuid",
      "property_name": "Apartment 2B",
      "role": "Tenant"
    }
  ]
}
```

---

## Bulk Operations

### Create Multiple Contacts
**POST** `/api/contacts/bulk`

Create multiple contacts in a single request.

**Request Body:**
```json
{
  "contacts": [
    {
      "type_contact": "Individual",
      "first_name": "Pierre",
      "last_name": "Dubois",
      "email": "pierre.dubois@example.com",
      "mobile": "+33612345679",
      "category": "Tenant",
      "address_line1": "100 Rue de Rivoli",
      "address_city": "Paris",
      "address_postal_code": "75001",
      "address_country": "France"
    },
    {
      "type_contact": "Company",
      "legal_name": "Gestion Immobiliere Rivoli",
      "registration_number": "12345678901234",
      "email": "contact@gestion-rivoli.fr",
      "mobile": "+33145678901",
      "category": "Property Manager",
      "address_line1": "200 Boulevard Haussman",
      "address_city": "Paris",
      "address_postal_code": "75009",
      "address_country": "France"
    }
  ]
}
```

**Response:** `201 Created`
Returns array of created contact objects.

### Delete Multiple Contacts
**DELETE** `/api/contacts/bulk`

Delete multiple contacts by their IDs.

**Request Body:**
```json
{
  "ids": [
    "550e8400-e29b-41d4-a716-446655440000",
    "550e8400-e29b-41d4-a716-446655440001"
  ]
}
```

**Response:** `204 No Content`

---

## Professional Fields

For professional contacts (property managers, agents, etc.), additional fields are available:

### Professional Information
- `professional_activity`: Type of professional activity
- `professional_card_number`: Professional license number
- `professional_card_issuing_location`: Where the card was issued
- `professional_card_issuing_date`: Issue date
- `professional_card_expiry_date`: Expiration date
- `professional_registration_number`: Registration number
- `professional_guarantor_id`: ID of professional guarantor
- `professional_insurance_company`: Insurance company name
- `professional_insurance_policy`: Policy number
- `professional_status`: Professional status enum

### ProfessionalStatus Enum
- `Active`: Currently active professional
- `Inactive`: Inactive professional
- `Suspended`: Temporarily suspended
- `Retired`: Retired professional

---

## Data Types

### Contact Types
- `Individual`: Personal contact
- `Company`: Business/organization contact

### Common Categories
- `Tenant`: Property tenant
- `Owner`: Property owner
- `Property Manager`: Property management professional
- `Contractor`: Service contractor
- `Legal Advisor`: Legal professional
- `Insurance Agent`: Insurance professional
- `Maintenance`: Maintenance personnel

---

## Error Responses

### Validation Errors
**400 Bad Request**
```json
{
  "error": "ValidationError",
  "message": "Invalid input data",
  "details": [
    {
      "field": "email",
      "message": "Valid email address is required"
    },
    {
      "field": "mobile",
      "message": "Mobile number must be between 1 and 20 characters"
    }
  ]
}
```

### Not Found
**404 Not Found**
```json
{
  "error": "NotFound",
  "message": "Contact not found"
}
```

### Conflict
**409 Conflict**
```json
{
  "error": "Conflict",
  "message": "Contact with this email already exists"
}
```

---

## Common Use Cases

### Creating a New Tenant
1. Create contact with `POST /api/contacts`
2. Set `type_contact` to "Individual" and `category` to "Tenant"
3. Include complete address and banking information
4. Associate with lease through lease endpoints

### Managing Property Manager Contacts
1. Create contact with professional fields populated
2. Set `professional_status` to "Active"
3. Include professional credentials and insurance information
4. Use the contact in property assignments

### Contact Search and Discovery
1. Use `GET /api/contacts/search` with search terms
2. Filter by category or type for specific contact groups
3. Use city/country filters for location-based searches

### Bulk Import of Contacts
1. Prepare contact data in required format
2. Use `POST /api/contacts/bulk` for batch creation
3. Handle validation errors for individual contacts

---

## Notes

- Email addresses must be unique across all contacts
- Mobile numbers are required for all contacts
- Professional fields are only relevant for business contacts
- Color codes should be valid hex colors (7 characters max)
- IBAN validation follows international standards
- All date fields use ISO 8601 format
- Address information is required for all contacts