# Locations

## Locations

The Locations resource is the primary way our system stores structured information about a Business location. It is a sub-resource of "Business" and also one or multiple locations can be assigned to a Site.

## Location Model

### Location object

A location object contains the following fields

| Attribute                  | Type      | Description                                                                                                                  |
| -------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------- |
| id                         | integer   | unique id of the location                                                                                                    |
| business\_id               | integer   | Reference id to the Business this location is under                                                                          |
| user\_id                   | integer   | Reference id to the User that created this business                                                                          |
| published                  | boolean   | Should this location show in Store Locators or Location directory modules. Default is `true`                                 |
| location\_name             | string    | Name of this location to identify different locations within a single Business                                               |
| street                     | string    | Street address                                                                                                               |
| street2                    | string    | Apartment or unit number                                                                                                     |
| city                       | string    | City                                                                                                                         |
| state                      | string    | State code                                                                                                                   |
| country                    | string    | 2 character country code                                                                                                     |
| postal\_code               | string    | Postal / zip code                                                                                                            |
| neighborhood               | string    | Neighborhood                                                                                                                 |
| phones                     | list      | Nested list of [Phone objects](#phone-object)                                                                                |
| description                | string    | HTML-formatted business description                                                                                          |
| partner\_location\_id      | string    | Unique ID reference to partner IDs                                                                                           |
| partner\_location\_sub\_id | string    | Non-unique ID reference to partner IDs                                                                                       |
| google\_places\_id         | string    | The Google Place ID for this location. When set can be used for optimized directions links and schema                        |
| directions\_url            | string    | Generated URL for Google Maps directions                                                                                     |
| hours                      | list      | Formatted JSON representing hours of operation. More details [here](#hours-of-operation)                                     |
| contact\_emails            | list      | Default contact emails for the business as a list of email address strings. Also used as the default recipients on forms     |
| payment\_forms             | list      | List of forms of payment accepted. [More details](#payment-forms-payment_forms)                                              |
| payment\_forms\_notes      | string    | Additional payment forms or notes                                                                                            |
| price\_range               | integer   | Price range indicated by `1-4` and used to represent `$-$$$$`                                                                |
| private\_street            | string    | Street address but used for service area businesses. This field will not be displayed by default on maps or within templates |
| service\_area\_only        | boolean   | Toggle to set this location as a "service-area only" business                                                                |
| service\_areas             | string    | Location service areas - neighborhoods, cities, zip codes                                                                    |
| services\_tags             | list      | List of service tags. [More info on service tags](#services-tags-services_tags)                                              |
| tagline                    | string    | Tagline or main headline for the location                                                                                    |
| year\_opened               | integer   | Year opened                                                                                                                  |
| careerplug\_url            | string    | Full url link to their careers page                                                                                          |
| facebook\_url              | string    | Full url link to their Facebook page                                                                                         |
| gplus\_url                 | string    | Full url link to their Google plus page                                                                                      |
| homepage\_url              | string    | Full url link to their external website if applicable                                                                        |
| instagram\_url             | string    | Full url link to their Instagram profile                                                                                     |
| linkedin\_url              | string    | Full url link to their LinkedIn profile                                                                                      |
| pinterest\_url             | string    | Full url link to their Pinterest page                                                                                        |
| twitter\_url               | string    | Full url link to their Twitter profile                                                                                       |
| yelp\_url                  | string    | Full url link to their Yelp profile                                                                                          |
| youtube\_url               | string    | Full url link to their Youtube page                                                                                          |
| added                      | timestamp | Date and time location was created                                                                                           |
| modified                   | timestamp | Date and time location was modified                                                                                          |
| automatic\_latlon          | boolean   | If true, we will automatically geocode the address and set the `lat` and `lon` fields                                        |
| extra\_schema              | object    | Assign additional schema.org values to a location. [More info](#extra-schema-org-extra_schema)                               |
| lat                        | float     | Latitude coordinate                                                                                                          |
| lon                        | float     | Longitude coordinate                                                                                                         |
| location\_url              | string    | Full url link to the location page associated with this location. This is used by our Store Locator module                   |
| custom\_fields             | object    | Custom field values assigned to the location for use in Location Finders, etc.                                               |

#### Example object:

```javascript
{
    "added": "2012-12-19T15:27:59",
    "automatic_latlon": true,
    "business_id": 12345,
    "city": "Seattle",
    "contact_emails": ["contact@ourdomain.com", "contact2@ourdomain.com"],
    "country": "US",
    "country_name": "United States of America",
    "custom_fields": {
        "headline_one": "Example headline one",
        "headline_two": "Example headline two",
        "bullet_points": [
            "Bullet point one",
            "Bullet point two"
        ]
    },
    "description": "<p>This is a business description</p>",
    "directions_url": "https://maps.google.com/maps/dir//...",
    "extra_schema": {
        "menu": "http://www.example.com/menu",
        "acceptsReservations": "True"
    },
    "facebook_url": "http://www.facebook.com/mypage/",
    "formatted_address": "555 Main St, Seattle, WA 98109",
    "geocoded": "555 Main St, Seattle, WA 98109, USA",
    "google_places_id": "ChIJgUbEo8cfqokR5lP9_Wh_DaM",
    "gplus_url": null,
    "homepage_url": "",
    "hours": [
        {
            "type": "primary",
            "hours": [
                [["09:00:00", "17:00:00"]],
                [["09:00:00", "17:00:00"]],
                [["09:00:00", "17:00:00"]],
                [["09:00:00", "17:00:00"]],
                [["09:00:00", "17:00:00"]],
                [],
                []
            ],
            "notes": "Open on saturday by appointment only",
            "special_hours": [
                {
                    "hours": [],
                    "start_date": "2020-09-07",
                    "end_date": "2020-09-07"
                },
                {
                    "hours": [["10:00:00", "15:00:00"]],
                    "start_date": "2020-09-11",
                    "end_date": "2020-09-14"
                }
            ]
        },
        {
            "type": "secondary",
            "hours": [
                [["09:00:00", "17:00:00"]],
                [["09:00:00", "17:00:00"]],
                [["09:00:00", "17:00:00"]],
                [["09:00:00", "17:00:00"]],
                [["09:00:00", "17:00:00"]],
                [],
                []
            ]
        }
    }
    "id": 1234,
    "instagram_url": null,
    "lat": "47.65015390000000",
    "linkedin_url": null,
    "location_name": "Belltown",
    "location_url": null,
    "lon": "-122.37786910000000",
    "modified": "2012-12-19T15:34:32",
    "neighborhood": "Queen Anne",
    "partner_location_id": "location-12345",
    "partner_location_sub_id": "region-1",
    "payment_forms": ["visa", "mastercard", "american-express"],
    "payment_forms_notes": null,
    "phonemap": {
        "phone": "(206) 930-7689"
    },
    "phonemap_e164": {
        "phone": "+12065555555"
    },
    "phones": [
        {
            "disable_autoformat": false,
            "e164": "(206) 930-7689",
            "extension": null,
            "id": 4321,
            "location_id": 1234,
            "number": "(206) 930-7689",
            "resource_uri": "/api/v2/phones/4321/",
            "type": "phone"
        }
    ],
    "pinterest_url": null,
    "postal_code": "98109",
    "price_range": 3,
    "private_street": null,
    "published": true,
    "resource_uri": "/api/v2/locations/1234/",
    "service_area_only": false,
    "service_areas": "Belltown, Downtown, South Lake Union",
    "services_tags": ["service-one", "service-two"],
    "state": "WA",
    "state_name": "Washington",
    "street": "555 Main St",
    "street2": "Apt 555",
    "tagline": null,
    "twitter_url": "https://twitter.com/mypage/",
    "user_id": 123,
    "year_opened": null,
    "yelp_url": null,
    "youtube_url": null
}
```

### Phone object (`phones`)

A phone object contains the following fields

| Attribute    | Type    | Description                                                          |
| ------------ | ------- | -------------------------------------------------------------------- |
| id           | integer | unique id of the phone                                               |
| location\_id | integer | Reference id to the Location this phone is under                     |
| type         | string  | type of the phone - options are `phone` `secondary` `tollfree` `fax` |
| number       | string  | Formatted version of the phone number                                |
| extension    | string  | Extension of the phone                                               |

### Hours of operation (`hours`)

Except for the special case formatting, this object is a list of 7 items which represent each day.

Each day can can have one-four time ranges. For example, two time ranges denotes a "lunch-break". No time ranges denotes closed.

* 9am-5pm `[["09:00:00", "17:00:00"]]`
* 9am-12pm and 1pm-5pm `[["09:00:00", "12:00:00"], ["13:00:00", "17:00:00"]]`
* Closed - send an empty list `[]`

#### Example of set of hours

```javascript
{
    "type": "primary",
    "hours": [
        [["09:00:00", "17:00:00"]],
        [["09:00:00", "17:00:00"]],
        [["09:00:00", "17:00:00"]],
        [["09:00:00", "17:00:00"]],
        [["09:00:00", "17:00:00"]],
        [],
        []
    ],
    "notes": "Open on saturday by appointment only",
    "special_hours": [
        {
            "hours": [],
            "start_date": "2020-09-07",
            "end_date": "2020-09-07"
        },
        {
            "hours": [["10:00:00", "15:00:00"]],
            "start_date": "2020-09-11",
            "end_date": "2020-09-14"
        }
    ]
}
```

#### Special case formatting

* 24 hours, for every day

```javascript
{
    "type": "primary",
    "hours": ["24_HOURS"]
}
```

### Extra Schema.org (`extra_schema`)

Our platform auto-generates location-based `JSON-LD` schema.org values for each location. This is embedded into any site that is published on the platform to syndicate these values to web search engines.

The `extra_schema` gives that ability to extend or replace the existing auto-generated schema values.

#### Example of automatic schema values

```javascript
{
    "@type": "LocalBusiness",
    "@context": "http://schema.org",
    "name": "Business Name",
    "telephone": "+12065555555",
    "address": {
        "@type": "PostalAddress",
        "addressLocality":"Seattle",
        "addressCountry":{
            "@type": "Country",
            "name": "US"
        },
        "addressRegion": "WA",
        "streetAddress": "555 Main St",
        "postalCode": "98101"
    },
    "openingHours": [
        "Mo 08:00-18:00",
        "Tu 08:00-18:00",
        "We 08:00-18:00",
        "Th 08:00-18:00",
        "Fr 08:00-16:00",
        "Sa 09:00-15:00"
    ],
    "geo":{
        "@type": "GeoCoordinates",
        "latitude": "47.61416580000000",
        "longitude": "-122.34258330000000"
    }
}
```

#### Example of extending schema for a restaurant

Using values specific to the `@type` of `Restaurant`.

```javascript
"extra_schema": {
    "menu": "http://www.example.com/menu",
    "acceptsReservations": "True"
}
```

### Payment forms (`payment_forms`)

Predefined list of payment forms supported by this location.

**List of all valid payment forms:** `visa`, `mastercard`, `american-express`, `discover`, `diners-club`, `debit`, `checks`, `credit-card`, `cash`, `vouchers`, `bank-deposit`, `money-orders`, `cashiers-checks`, `paypal`, `financing-available`, `carecredit`, `most-insurance-plans`, `layaway`, `money-transfers`, `line-of-credit`, `store-card`, `google-wallet`, `travelers-checks`, `invoice`, `cheque`, `interac`

#### Example of sending payment forms

Note. These are always sent as lowercase.

```javascript
"payment_forms": ["visa", "mastercard", "american-express"]
```

### Services tags (`services_tags`)

These are structured tags that can be assigned to a location. These are primarily used for filtering [Location Finder](https://docs.devhub.com/maps/location-finder) results. But these tags can also be used within templates to hide and show content or build a list of applicable services.

These tags should be lowercase and can contain alphanumeric and dashes (`-`) characters.

```javascript
"services_tags": ["service-one", "service-two"]
```

## Create a location

`POST /api/v2/locations/`

### Required fields - Normal location

| Attribute    |
| ------------ |
| business\_id |
| street       |
| city         |
| state        |
| postal\_code |
| country      |

### Required fields - Service area only location

| Attribute    |
| ------------ |
| business\_id |
| city         |
| state        |
| postal\_code |
| country      |

## List locations

List all locations for all businesses

```javascript
GET /api/v2/locations/
```

List all locations for a particular business

```javascript
GET /api/v2/locations/?business_id=12345 
```

### Parameters

| Name                  | Type     | Description                                                                                                     |
| --------------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
| `business_id`         | `string` | Filter for locations associated with a particular `Business`                                                    |
| `near_lat`            | `float`  | Latitude to use in nearby location searches. See [Distance Search](#distance-search) for more details           |
| `near_location`       | `string` | Location search string to find nearby locations. See [Distance Search](#distance-search) for more details       |
| `near_lon`            | `float`  | Longitude to use in nearby location searches. See [Distance Search](#distance-search) for more details          |
| `partner_business_id` | `string` | Used to lookup/search for locations matching a particular internal id                                           |
| `partner_location_id` | `string` | Used to lookup/search for locations matching a particular internal id                                           |
| `threshold`           | `int`    | Distance in miles to restrict distance search results. See [Distance Search](#distance-search) for more details |

### Distance search

Locations can be searched and ordered by distance from a particular point or searched location (`near_location`) string like a postal code or city/state.

```javascript
GET /api/v2/locations/?
    business_id=12345&
    near_location=98121&
    threshold=4000&
    limit=20
```

If you already have the search location (latitude and longitude), you can pass those directly into the request using `near_lat` and `near_lon` to speed up the response time and avoid an API call to geocode the search.

```javascript
GET /api/v2/locations/?
    business_id=12345&
    near_lat=47.6139939&
    near_lon=-122.34235389999999
    threshold=4000&
    limit=20
```

#### Additional values

For these distance searches, we also add additional values to the response with some location and distance context.

In the resulting response `meta` we will add the latitude and longitude of the searched point for reference.

```json
{
    "meta": {
        "lat": 47.6062095,
        "lon": -122.3320708,
        ...
    }
}
```

In each of the the resulting Location objects, we add`distance` (in miles or km depending on the project configuration).

```javascript
"objects": [{
    "id": 123456,
    "location_name": "Belltown",
    ...
    "distance": 996.79
}]
```

## Update a location

`PUT /api/v2/locations/:location_id/`

## Delete a location

`DELETE /api/v2/locations/:location_id/`
