> ## Documentation Index
> Fetch the complete documentation index at: https://twigz.arqqin.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Customer Addresses

> Customer address management for delivery locations

## Overview

The Customer Addresses API provides comprehensive address management functionality for customers, including creating, updating, deleting, and managing delivery addresses. This system supports multiple addresses per customer with default address selection and geographic information.

**Location:** `convex/customers/addresses.ts`

## Create Address

Create a new delivery address for a customer.

<ParamField path="customerId" type="Id<'customers'>" required>
  The ID of the customer to create the address for
</ParamField>

<ParamField path="name" type="string" required>
  A descriptive name for the address (e.g., "Home", "Office")
</ParamField>

<ParamField path="fullAddress" type="string" required>
  The complete address string
</ParamField>

<ParamField path="city" type="Id<'cities'>" required>
  The ID of the city for this address
</ParamField>

<ParamField path="area" type="Id<'areas'>" required>
  The ID of the area within the city
</ParamField>

<ParamField path="flatVilaNumber" type="string" optional>
  Flat or villa number
</ParamField>

<ParamField path="buildingNameNumber" type="string" optional>
  Building name or number
</ParamField>

<ParamField path="landmark" type="string" optional>
  Nearby landmark for easier location
</ParamField>

<ParamField path="latitude" type="string" optional>
  GPS latitude coordinate
</ParamField>

<ParamField path="longitude" type="string" optional>
  GPS longitude coordinate
</ParamField>

<ParamField path="isDefault" type="boolean" optional>
  Whether this should be the default address for the customer
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  const addressId = await convex.mutation(api.customers.addresses.createAddress, {
    customerId: "k123456789",
    name: "Home",
    fullAddress: "123 Main Street, Apartment 2B",
    city: "c987654321",
    area: "a456789123",
    flatVilaNumber: "2B",
    buildingNameNumber: "Al Noor Building",
    landmark: "Near City Mall",
    latitude: "25.2048",
    longitude: "55.2708",
    isDefault: true
  });
  ```

  ```javascript JavaScript theme={null}
  const addressId = await convex.mutation("customers.addresses.createAddress", {
    customerId: "k123456789",
    name: "Office",
    fullAddress: "456 Business District",
    city: "c987654321",
    area: "a789123456",
    isDefault: false
  });
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      f"{CONVEX_URL}/api/mutation",
      json={
          "path": "customers.addresses.createAddress",
          "args": {
              "customerId": "k123456789",
              "name": "Home",
              "fullAddress": "123 Main Street, Apartment 2B",
              "city": "c987654321",
              "area": "a456789123",
              "isDefault": True
          }
      },
      headers={"Authorization": f"Bearer {token}"}
  )

  address_id = response.json()
  ```
</CodeGroup>

**Returns:** `Id<'customerAddresses'>` - The ID of the newly created address

***

## Update Address

Update an existing customer address. Only provided fields will be updated.

<ParamField path="addressId" type="Id<'customerAddresses'>" required>
  The ID of the address to update
</ParamField>

<ParamField path="name" type="string" optional>
  Updated address name
</ParamField>

<ParamField path="fullAddress" type="string" optional>
  Updated full address
</ParamField>

<ParamField path="city" type="Id<'cities'>" optional>
  Updated city ID
</ParamField>

<ParamField path="area" type="Id<'areas'>" optional>
  Updated area ID
</ParamField>

<ParamField path="flatVilaNumber" type="string" optional>
  Updated flat/villa number
</ParamField>

<ParamField path="buildingNameNumber" type="string" optional>
  Updated building name/number
</ParamField>

<ParamField path="landmark" type="string" optional>
  Updated landmark
</ParamField>

<ParamField path="latitude" type="string" optional>
  Updated latitude
</ParamField>

<ParamField path="longitude" type="string" optional>
  Updated longitude
</ParamField>

<ParamField path="isDefault" type="boolean" optional>
  Whether this should be the default address
</ParamField>

<ParamField path="isActive" type="boolean" optional>
  Whether the address is active
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  await convex.mutation(api.customers.addresses.updateAddress, {
    addressId: "a123456789",
    name: "Updated Home Address",
    flatVilaNumber: "3A",
    landmark: "Near New Shopping Center",
    isDefault: true
  });
  ```

  ```javascript JavaScript theme={null}
  await convex.mutation("customers.addresses.updateAddress", {
    addressId: "a123456789",
    fullAddress: "789 New Street, Updated Location",
    city: "c111222333",
    area: "a333222111"
  });
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      f"{CONVEX_URL}/api/mutation",
      json={
          "path": "customers.addresses.updateAddress",
          "args": {
              "addressId": "a123456789",
              "name": "Updated Office",
              "isDefault": False
          }
      },
      headers={"Authorization": f"Bearer {token}"}
  )
  ```
</CodeGroup>

**Returns:** `null`

***

## Delete Address

Delete a customer address.

<ParamField path="addressId" type="Id<'customerAddresses'>" required>
  The ID of the address to delete
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  await convex.mutation(api.customers.addresses.deleteAddress, {
    addressId: "a123456789"
  });
  ```

  ```javascript JavaScript theme={null}
  await convex.mutation("customers.addresses.deleteAddress", {
    addressId: "a123456789"
  });
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      f"{CONVEX_URL}/api/mutation",
      json={
          "path": "customers.addresses.deleteAddress",
          "args": {
              "addressId": "a123456789"
          }
      },
      headers={"Authorization": f"Bearer {token}"}
  )
  ```
</CodeGroup>

**Returns:** `null`

***

## Get Customer Addresses

Retrieve all active addresses for a customer, sorted with default address first.

<ParamField path="customerId" type="Id<'customers'>" optional>
  The customer ID. If not provided, uses the authenticated user's customer profile
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  const addresses = await convex.query(api.customers.addresses.getCustomerAddresses, {
    customerId: "k123456789" // Optional
  });
  ```

  ```javascript JavaScript theme={null}
  // Get addresses for authenticated user
  const addresses = await convex.query("customers.addresses.getCustomerAddresses", {});

  // Get addresses for specific customer
  const specificAddresses = await convex.query("customers.addresses.getCustomerAddresses", {
    customerId: "k123456789"
  });
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      f"{CONVEX_URL}/api/query",
      json={
          "path": "customers.addresses.getCustomerAddresses",
          "args": {
              "customerId": "k123456789"  # Optional
          }
      },
      headers={"Authorization": f"Bearer {token}"}
  )

  addresses = response.json()
  ```
</CodeGroup>

**Returns:** Array of address objects with enriched city and area information:

```typescript theme={null}
{
  _id: Id<'customerAddresses'>,
  _creationTime: number,
  name: string,
  fullAddress: string,
  city: {
    _id: Id<'cities'>,
    name: string,
    nameArabic: string
  },
  area: {
    _id: Id<'areas'>,
    name: string,
    city: Id<'cities'>
  },
  flatVilaNumber?: string,
  buildingNameNumber?: string,
  landmark?: string,
  latitude?: string,
  longitude?: string,
  isDefault?: boolean,
  isActive?: boolean
}[]
```

***

## Get Address

Retrieve a specific address by ID with full details.

<ParamField path="addressId" type="Id<'customerAddresses'>" required>
  The ID of the address to retrieve
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  const address = await convex.query(api.customers.addresses.getAddress, {
    addressId: "a123456789"
  });
  ```

  ```javascript JavaScript theme={null}
  const address = await convex.query("customers.addresses.getAddress", {
    addressId: "a123456789"
  });
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      f"{CONVEX_URL}/api/query",
      json={
          "path": "customers.addresses.getAddress",
          "args": {
              "addressId": "a123456789"
          }
      },
      headers={"Authorization": f"Bearer {token}"}
  )

  address = response.json()
  ```
</CodeGroup>

**Returns:** Address object with enriched details or `null` if not found:

```typescript theme={null}
{
  _id: Id<'customerAddresses'>,
  _creationTime: number,
  customerId: Id<'customers'>,
  name: string,
  fullAddress: string,
  city: {
    _id: Id<'cities'>,
    name: string,
    nameArabic: string
  },
  area: {
    _id: Id<'areas'>,
    name: string,
    city: Id<'cities'>
  },
  flatVilaNumber?: string,
  buildingNameNumber?: string,
  landmark?: string,
  latitude?: string,
  longitude?: string,
  isDefault?: boolean,
  isActive?: boolean
} | null
```

***

## Set Default Address

Set a specific address as the default for a customer. This will unset any existing default address.

<ParamField path="addressId" type="Id<'customerAddresses'>" required>
  The ID of the address to set as default
</ParamField>

<CodeGroup>
  ```typescript TypeScript theme={null}
  await convex.mutation(api.customers.addresses.setDefaultAddress, {
    addressId: "a123456789"
  });
  ```

  ```javascript JavaScript theme={null}
  await convex.mutation("customers.addresses.setDefaultAddress", {
    addressId: "a123456789"
  });
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      f"{CONVEX_URL}/api/mutation",
      json={
          "path": "customers.addresses.setDefaultAddress",
          "args": {
              "addressId": "a123456789"
          }
      },
      headers={"Authorization": f"Bearer {token}"}
  )
  ```
</CodeGroup>

**Returns:** `null`

***

## Authentication & Authorization

All address operations require authentication and implement proper authorization:

* **User Authentication**: All functions verify the user is authenticated through Clerk
* **Ownership Verification**: Users can only manage their own addresses
* **Customer Association**: Addresses are tied to customer profiles, which are linked to authenticated users

## Default Address Management

The system automatically manages default addresses:

* Only one address per customer can be marked as default
* Setting a new default automatically unsets the previous default
* Default addresses appear first in address listings
* Default address logic is handled in `createAddress`, `updateAddress`, and `setDefaultAddress`

## Geographic Information

Addresses include geographic data for delivery optimization:

* **City and Area References**: Links to city and area entities for structured location data
* **GPS Coordinates**: Optional latitude/longitude for precise location
* **Address Validation**: Ensures referenced cities and areas exist before creating/updating addresses

## Error Handling

Common error scenarios:

* **Unauthorized**: User not authenticated or trying to access another user's addresses
* **Not Found**: Address, city, or area doesn't exist
* **Invalid References**: Invalid city or area IDs provided
* **Ownership Mismatch**: Attempting to modify addresses belonging to other customers
