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

# Address Book — Manage Shipping and Billing Addresses

> Manage your saved addresses for shipping and billing. Create, update, set defaults, and delete addresses from your account address book.

Your address book stores shipping and billing addresses that you can attach to orders at checkout. Each address can be independently flagged as the default for shipping, for billing, or for both. The API returns addresses in reverse chronological order (newest first) and automatically manages default promotion when an address is deleted.

<Tip>
  Address public IDs (prefixed with `adr_`) are what you pass when placing an order. Save them in your frontend after creation to reference them during checkout without fetching the full list.
</Tip>

<Note>
  The **first address you create** is automatically set as both the default shipping and the default billing address, regardless of the `is_default_shipping` and `is_default_billing` values in the request body.
</Note>

***

## List Addresses

Retrieve a paginated list of your saved addresses, ordered newest first.

**`GET /users/me/addresses`**

### Query Parameters

<ParamField query="page" type="integer" default="1">
  Page number (1-based).
</ParamField>

<ParamField query="limit" type="integer" default="20">
  Number of addresses to return per page. Minimum `1`, maximum `100`.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://api.example.com/api/v1/users/me/addresses?page=1&limit=20" \
    --cookie "session=<your-session-cookie>"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://api.example.com/api/v1/users/me/addresses?page=1&limit=20",
    { credentials: "include" }
  );
  const { data, meta } = await response.json();
  ```

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

  resp = requests.get(
      "https://api.example.com/api/v1/users/me/addresses",
      params={"page": 1, "limit": 20},
      cookies={"session": "<your-session-cookie>"},
  )
  result = resp.json()
  ```
</CodeGroup>

### Response — 200 OK

```json theme={null}
{
  "success": true,
  "data": [
    {
      "public_id": "adr_01H",
      "recipient_name": "Jane Doe",
      "phone_number": "+14155552671",
      "label": "Home",
      "country": "USA",
      "state": "CA",
      "city": "San Francisco",
      "address_1": "123 Market St",
      "address_2": "Apt 4B",
      "zip_code": "94105",
      "is_default_shipping": true,
      "is_default_billing": true,
      "created_at": "2024-01-15T10:30:00.000Z",
      "updated_at": "2024-01-15T10:30:00.000Z"
    }
  ],
  "meta": {
    "total": 1,
    "totalPages": 1,
    "hasNext": false,
    "hasPrev": false
  }
}
```

***

## Create an Address

Add a new address to your address book. The required fields are `recipient_name`, `phone_number`, `country`, `state`, `city`, and `address_1`. All other fields are optional.

**`POST /users/me/addresses`**

<Note>
  Obtain a CSRF token from `GET /auth/csrf-token` and pass it in the `x-csrf-token` header before this and all other write requests.
</Note>

### Request Body

<ParamField body="recipient_name" type="string" required>
  Full name of the person receiving the delivery. 1–100 characters.
</ParamField>

<ParamField body="phone_number" type="string" required>
  Contact phone number for the recipient. Up to 20 characters (e.g. `+14155552671`).
</ParamField>

<ParamField body="country" type="string" required>
  Country name or code (e.g. `USA`, `GB`). 1–100 characters.
</ParamField>

<ParamField body="state" type="string" required>
  State, province, or region. 1–100 characters.
</ParamField>

<ParamField body="city" type="string" required>
  City or locality. 1–100 characters.
</ParamField>

<ParamField body="address_1" type="string" required>
  Primary street address line. Minimum 1 character.
</ParamField>

<ParamField body="label" type="string">
  Friendly label for this address, e.g. `Home` or `Office`. Up to 50 characters.
</ParamField>

<ParamField body="address_2" type="string">
  Secondary address line for apartment, suite, unit, etc. (e.g. `Apt 4B`).
</ParamField>

<ParamField body="zip_code" type="string">
  Postal or ZIP code. Up to 20 characters.
</ParamField>

<ParamField body="is_default_shipping" type="boolean" default="false">
  Set this address as your default shipping address. Setting this to `true` clears the flag from whichever address currently holds it.
</ParamField>

<ParamField body="is_default_billing" type="boolean" default="false">
  Set this address as your default billing address. Setting this to `true` clears the flag from whichever address currently holds it.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  # Step 1 — get CSRF token
  CSRF=$(curl -s -X GET https://api.example.com/api/v1/auth/csrf-token \
    --cookie "session=<your-session-cookie>" | jq -r '.data.csrf_token')

  # Step 2 — create address
  curl -X POST https://api.example.com/api/v1/users/me/addresses \
    --cookie "session=<your-session-cookie>" \
    -H "x-csrf-token: $CSRF" \
    -H "Content-Type: application/json" \
    -d '{
      "recipient_name": "Jane Doe",
      "phone_number": "+14155552671",
      "label": "Home",
      "country": "USA",
      "state": "CA",
      "city": "San Francisco",
      "address_1": "123 Market St",
      "address_2": "Apt 4B",
      "zip_code": "94105",
      "is_default_shipping": true,
      "is_default_billing": true
    }'
  ```

  ```javascript JavaScript theme={null}
  const { data: csrfData } = await fetch(
    "https://api.example.com/api/v1/auth/csrf-token",
    { credentials: "include" }
  ).then((r) => r.json());

  const response = await fetch(
    "https://api.example.com/api/v1/users/me/addresses",
    {
      method: "POST",
      credentials: "include",
      headers: {
        "Content-Type": "application/json",
        "x-csrf-token": csrfData.csrf_token,
      },
      body: JSON.stringify({
        recipient_name: "Jane Doe",
        phone_number: "+14155552671",
        label: "Home",
        country: "USA",
        state: "CA",
        city: "San Francisco",
        address_1: "123 Market St",
        address_2: "Apt 4B",
        zip_code: "94105",
        is_default_shipping: true,
        is_default_billing: true,
      }),
    }
  );
  const { data } = await response.json();
  console.log(data.public_id); // "adr_01H"
  ```

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

  s = requests.Session()
  s.cookies.set("session", "<your-session-cookie>")

  csrf = s.get(
      "https://api.example.com/api/v1/auth/csrf-token"
  ).json()["data"]["csrf_token"]

  resp = s.post(
      "https://api.example.com/api/v1/users/me/addresses",
      headers={"x-csrf-token": csrf},
      json={
          "recipient_name": "Jane Doe",
          "phone_number": "+14155552671",
          "label": "Home",
          "country": "USA",
          "state": "CA",
          "city": "San Francisco",
          "address_1": "123 Market St",
          "address_2": "Apt 4B",
          "zip_code": "94105",
          "is_default_shipping": True,
          "is_default_billing": True,
      },
  )
  print(resp.json()["data"]["public_id"])  # "adr_01H"
  ```
</CodeGroup>

### Response — 201 Created

```json theme={null}
{
  "success": true,
  "data": {
    "public_id": "adr_01H",
    "recipient_name": "Jane Doe",
    "phone_number": "+14155552671",
    "label": "Home",
    "country": "USA",
    "state": "CA",
    "city": "San Francisco",
    "address_1": "123 Market St",
    "address_2": "Apt 4B",
    "zip_code": "94105",
    "is_default_shipping": true,
    "is_default_billing": true,
    "created_at": "2024-01-15T10:30:00.000Z",
    "updated_at": "2024-01-15T10:30:00.000Z"
  }
}
```

<Expandable title="Response fields">
  <ResponseField name="public_id" type="string" required>
    Unique address identifier prefixed with `adr_`. Use this when placing orders.
  </ResponseField>

  <ResponseField name="recipient_name" type="string" required>
    Full name of the delivery recipient.
  </ResponseField>

  <ResponseField name="phone_number" type="string" required>
    Contact number for the recipient at this address.
  </ResponseField>

  <ResponseField name="label" type="string">
    Optional friendly label, e.g. `Home` or `Work`.
  </ResponseField>

  <ResponseField name="country" type="string" required>
    Country for this address.
  </ResponseField>

  <ResponseField name="state" type="string" required>
    State, province, or region.
  </ResponseField>

  <ResponseField name="city" type="string" required>
    City or locality.
  </ResponseField>

  <ResponseField name="address_1" type="string" required>
    Primary street address line.
  </ResponseField>

  <ResponseField name="address_2" type="string">
    Secondary address line (apartment, suite, etc.). May be `null`.
  </ResponseField>

  <ResponseField name="zip_code" type="string">
    Postal or ZIP code.
  </ResponseField>

  <ResponseField name="is_default_shipping" type="boolean" required>
    Whether this address is used by default for shipping at checkout.
  </ResponseField>

  <ResponseField name="is_default_billing" type="boolean" required>
    Whether this address is used by default for billing at checkout.
  </ResponseField>

  <ResponseField name="created_at" type="string" required>
    ISO 8601 UTC timestamp of when the address was created.
  </ResponseField>

  <ResponseField name="updated_at" type="string" required>
    ISO 8601 UTC timestamp of the last update.
  </ResponseField>
</Expandable>

### Error Responses

| Status | Meaning                                                           |
| ------ | ----------------------------------------------------------------- |
| `400`  | A required field is missing or fails validation.                  |
| `401`  | Missing or expired session cookie.                                |
| `409`  | A default flag conflict that could not be resolved automatically. |

***

## Get a Single Address

Retrieve one address from your address book by its public ID.

**`GET /users/me/addresses/{address_public_id}`**

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://api.example.com/api/v1/users/me/addresses/adr_01H \
    --cookie "session=<your-session-cookie>"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://api.example.com/api/v1/users/me/addresses/adr_01H",
    { credentials: "include" }
  );
  const { data } = await response.json();
  ```
</CodeGroup>

### Response — 200 OK

Returns a single [Address object](#response--201-created) identical in shape to the creation response.

| Status | Meaning                                               |
| ------ | ----------------------------------------------------- |
| `401`  | Missing or expired session cookie.                    |
| `404`  | Address not found or does not belong to your account. |

***

## Update an Address

Partially update an existing address. Supply only the fields you want to change — all others remain unchanged. Default flag changes trigger automatic promotion or clearing of the existing defaults.

**`PATCH /users/me/addresses/{address_public_id}`**

The request body accepts the same fields as [Create an Address](#create-an-address), all optional. At minimum, send one field to change.

<CodeGroup>
  ```bash cURL theme={null}
  CSRF=$(curl -s -X GET https://api.example.com/api/v1/auth/csrf-token \
    --cookie "session=<your-session-cookie>" | jq -r '.data.csrf_token')

  curl -X PATCH https://api.example.com/api/v1/users/me/addresses/adr_01H \
    --cookie "session=<your-session-cookie>" \
    -H "x-csrf-token: $CSRF" \
    -H "Content-Type: application/json" \
    -d '{"label": "Office", "address_1": "456 Mission St"}'
  ```

  ```javascript JavaScript theme={null}
  const { data: csrfData } = await fetch(
    "https://api.example.com/api/v1/auth/csrf-token",
    { credentials: "include" }
  ).then((r) => r.json());

  const response = await fetch(
    "https://api.example.com/api/v1/users/me/addresses/adr_01H",
    {
      method: "PATCH",
      credentials: "include",
      headers: {
        "Content-Type": "application/json",
        "x-csrf-token": csrfData.csrf_token,
      },
      body: JSON.stringify({ label: "Office", address_1: "456 Mission St" }),
    }
  );
  ```
</CodeGroup>

### Response — 200 OK

Returns the full updated address object.

| Status | Meaning                                               |
| ------ | ----------------------------------------------------- |
| `400`  | Validation error on one of the supplied fields.       |
| `401`  | Missing or expired session cookie.                    |
| `404`  | Address not found or does not belong to your account. |
| `409`  | Default flag conflict.                                |

***

## Delete an Address

Soft-delete an address from your address book. The address is removed from your active list and can no longer be used for new orders.

**`DELETE /users/me/addresses/{address_public_id}`**

<Info>
  When you delete an address that is currently set as a default (shipping or billing), the **next oldest address** in your book is automatically promoted to hold that default flag — so your checkout flow is never left without a default.
</Info>

<CodeGroup>
  ```bash cURL theme={null}
  CSRF=$(curl -s -X GET https://api.example.com/api/v1/auth/csrf-token \
    --cookie "session=<your-session-cookie>" | jq -r '.data.csrf_token')

  curl -X DELETE https://api.example.com/api/v1/users/me/addresses/adr_01H \
    --cookie "session=<your-session-cookie>" \
    -H "x-csrf-token: $CSRF"
  ```

  ```javascript JavaScript theme={null}
  const { data: csrfData } = await fetch(
    "https://api.example.com/api/v1/auth/csrf-token",
    { credentials: "include" }
  ).then((r) => r.json());

  await fetch(
    "https://api.example.com/api/v1/users/me/addresses/adr_01H",
    {
      method: "DELETE",
      credentials: "include",
      headers: { "x-csrf-token": csrfData.csrf_token },
    }
  );
  // 204 No Content on success
  ```
</CodeGroup>

### Response — 204 No Content

No response body is returned.

| Status | Meaning                                               |
| ------ | ----------------------------------------------------- |
| `401`  | Missing or expired session cookie.                    |
| `404`  | Address not found or does not belong to your account. |
