> For the complete documentation index, see [llms.txt](https://docs.genlogs.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.genlogs.io/shipper/shipper-facilities.md).

# Shipper Facilities

The facilities endpoint allows users to retrieve a list of facilities that match a given name, location, and search radius. The response includes detailed information about each facility, such as contact information, geographic coordinates, and operating hours.

### **Authentication**

Include the following headers in your requests:

* **Access-Token**: The access token obtained from the "Create Access Token" endpoint.
* **x-api-key:** The API key provided by GenLogs. This header must be included in the request.

### Permissions

Make sure that your api user is created with a role that has `external-api-shipper-facilities` permission

### **Endpoint**

* **URL**: `https://api.genlogs.io/facilities`
* **Method**: `GET`

### **Query Parameters**

* **`name`** *(string, max 500 chars, required — only optional when `address`, `website_domain`, or a `city` + `state` combination is provided)* The name of the facility to search for. For example, `"Acme Logistics"`.&#x20;
* **`address`** *(string, max 500 chars, required — only optional when `name`, `website_domain`, or a `city` + `state` combination is provided)* The address of the facility to search for. For example, `"123 Main Street South"`.
* **`city`** *(string, max 150 chars, required — only optional when `name`, `address`, or `website_domain` is provided)* The location "city" around which to search for facilities. For example, `"Boston"` or `"Atlanta"`. Must be sent together with `state` and must geocode successfully; unrecognized locations return empty.
* **`state`** *(string, max 150 chars, required — only optional when `name`, `address`, or `website_domain` is provided)* The location "state" around which to search for facilities. For example, `"Massachusetts"` or `"Georgia"`. Must be sent together with `city` and must geocode successfully; unrecognized locations return empty.
* **`website_domain`** *(string, optional, max 253 chars)* Returns facilities whose stored contact URL contains the given domain. Provide the bare host only — e.g. `acme.com`, not `https://www.acme.com/about`. The match is case-insensitive and anchored on the host substring, so `acme.com` will match stored URLs like `https://www.acme.com/contact`, `http://shipping.acme.com`, and `acme.com.au`. Minimum accepted form is `a.com` (must contain a `.` and a 2+ character TLD). Shorter inputs return HTTP 400.

{% hint style="info" %}
**`website_domain` vs. `contact_url` in the response.** `website_domain` is an *input filter* — the value you send to narrow the search. `contact_url` is the *output field* on each facility record and holds the full URL as Genlogs ingested it (scheme, subdomain, path, and all). The filter is a substring match against `contact_url`, so the two will usually look related but rarely identical: you filter by `acme.com` and get back facilities whose `contact_url` is `https://www.acme.com/locations/12`. Do not expect `contact_url` to echo the domain you sent.
{% endhint %}

* **`radius`** *(number, optional, default `20`, max `150`)* The radius in miles within which to search around the specified location. Only takes effect when paired with a successful `city` + `state` geocode — sent alone, it has no effect.
* **`lot_size_category`** *(string, optional, max 50 chars)* Filter by the lot size category of the facility. Accepts one or more of `Small`, `Medium`, `Large`, `X-Large`. To pass multiple values, separate them with a pipe — e.g. `Small | Medium`. Matching is case-insensitive.

{% hint style="info" %}
**Filter precedence.** `name`, `address`, and `website_domain` are mutually exclusive text filters. If you send more than one, only the highest-priority filter is applied (`name` > `address` > `website_domain`) — the others are silently ignored.&#x20;

**Geographic narrowing** is layered on top of whichever text filter wins:

* `city` + `state` must both be sent and must geocode successfully; unrecognized locations are dropped silently and return ungeoed results.

* `radius` (miles) only takes effect when paired with a successful `city` + `state` geocode. Sent alone, it has no effect.
  {% endhint %}

* **`zip_code`** *(string, optional, max 10 chars)* Search for facilities by valid US zip code. Can be combined with other search parameters like **`name`** or **`address`** to further narrow results.

* **`include_lanes`** *(string, optional)* Accepts only *true*, each facility in the response includes inbound\_lanes and outbound\_lanes arrays containing structured freight lane data ranked by weight. Facilities with no matching lane data are excluded from the response. Enables pagination — see *cursor* below.&#x20;

{% hint style="info" %}
**Lane Data Behavior.** When include\_lanes=true is sent, the response changes in several ways:

* Each facility includes inbound\_lanes and outbound\_lanes arrays ranked by weight

* Facilities with no matching lane data are excluded from the response

* Results are paginated at 20 facilities per page — check the Link response header for the next page URL

* The limit parameter is capped at 20 regardless of the value provided

* Lane-specific filters (**`top_n`**, **`min_distance`**, **`direction`**) only take effect in this mode

* Without include\_lanes=true, none of the above applies — the response contains facility metadata only, no pagination headers, and limit follows the standard defaults.
  {% endhint %}

* **`top_n`** *(number, optional, default 10, max 50)* The number of top lanes to return per direction (inbound/outbound) per facility, ranked by weight descending. For example, top\_n=5 returns the 5 highest-weighted inbound and 5 highest-weighted outbound lanes. Only takes effect when **`include_lanes`**=true.

* **`min_distance`** *(number, optional, miles)* Minimum distance in miles from the facility to a lane destination. Lanes closer than this threshold are excluded. For example, min\_distance=200 returns only lanes where the destination is 200+ miles away. Applied before **`top_n`**. Only takes effect when **`include_lanes`**=true.

* **`direction`** *(string, optional, one of: N, S, E, W, NE, NW, SE, SW)* Filter lanes by compass direction from the facility. For example, **`direction`**=NE returns only lanes heading northeast. Applied before **`top_n`**. Only takes effect when **`include_lanes`**=true.

* **`limit`** *(number, optional)* Filter lanes by compass direction from the facility. For example, **`direction`**=NE returns only lanes heading northeast. Applied before **`top_n`**. Only takes effect when **`include_lanes`**=true.

* **`cursor`** *(string, optional, opaque)* Pagination cursor from the Link response header of a previous request. Do not construct, parse, or cache this value — follow the URL provided in the Link header. Only present in responses when **`include_lanes`**=true and results exceed 20 facilities.&#x20;

### **Response**

* **200 OK**: Successfully retrieved the list of facilities matching the search criteria.
* **400 Bad Request**: If required parameters are missing or invalid.
* **401 Unauthorized**: If the `Access-Token` or `x-api-key` is missing or invalid.
* **500 Internal Server Error**: If an error occurs on the server while processing the request.

### **Response Body**

* **facilities** (array of `Facility` objects): List of up to 1,000 facilities matching the search criteria ordered by relative load volume.
  * **contact\_phone** (nullable string): Phone number of the facility's contact person.
  * **contact\_url** (nullable string): URL for the facility's contact page or website.
  * **facility\_name** (string): Name of the facility.
  * **formatted\_address** (string): Full address of the facility.
  * **id** (string): Unique identifier for the facility.
  * **inbound\_lanes** (array): Lanes inbound to a facility, ranked by weight descending.
  * **lat** (number): Latitude of the facility's location.
  * **lon** (number): Longitude of the facility's location.
  * **operating\_hours** (nullable string): Operating hours of the facility.
  * **outbound\_lanes** (array): Lanes outbound from a facility, ranked by weight descending.
  * **place\_category** (string): Category or type of place (e.g., warehouse, distribution center).
  * **place\_desc** (String): Description of the facility
  * **equipment\_pairings** (List): Equipment types paired with this facility based on observed carrier activity.

### Request Example:

Search by `name` + `city` and `state`.

```sh
curl -X GET 'https://api.genlogs.io/facilities?name=coca+cola&city=&state=&radius=50' \
-H 'Access-Token: {access_token}' \
-H 'x-api-key: {your_api_key}' \
```

Search by `address`&#x20;

```shellscript
curl -X GET 'https://api.genlogs.io/facilities?address=123%20Main%20Street%20South' \
-H 'Access-Token: {access_token}' \
-H 'x-api-key: {your_api_key}' \
```

Search by `zip_code`&#x20;

```shellscript
curl -X GET 'https://api.genlogs.io/facilities?zip_code=12345' \
-H 'Access-Token: {access_token}' \
-H 'x-api-key: {your_api_key}' \
```

## Search facilities by name, address, zip code, city/state, website domain, or coordinates

> Unified facility search. Provide at least one of: non-empty \*\*\`name\`\*\*, non-empty \*\*\`address\`\*\*, \*\*\`zip\_code\`\*\*, non-empty \*\*\`website\_domain\`\*\*, or both \*\*\`city\`\*\* and \*\*\`state\`\*\* (then use \*\*\`radius\`\*\* around the geocoded point). You may also pass \*\*\`location\`\*\* as \`latitude,longitude\` for radius search instead of city/state.\
> Optionally include lane data per facility with \*\*\`include\_lanes=true\`\*\*. Lanes can be filtered by \*\*\`min\_distance\`\*\* (miles from facility) and \*\*\`direction\`\*\* (compass direction). Filters are applied before the \*\*\`top\_n\`\*\* limit.\
> \
> \## Pagination\
> \
> When results exceed 100 facilities, the response is paginated using opaque cursor-based pagination. The \`Link\` response header contains a next-page URL with a \`cursor\` parameter. Follow that URL to retrieve subsequent pages. The \`X-Total-Count\` header shows the total matching facilities across all pages. Pagination is not supported with \`smart\_search=true\`.\
> See component schema \*\*FacilitiesQueryCriteria\*\* for the full parameter model and validation shape.\
> Historical path \`/find\_facilities\` exposes the same search behavior and is documented here as \*\*\`/facilities\`\*\* for a single contract.<br>

```json
{"openapi":"3.0.2","info":{"title":"Shipper API","version":"1.0.0"},"servers":[{"url":"https://api.genlogs.io"}],"paths":{"/facilities":{"get":{"summary":"Search facilities by name, address, zip code, city/state, website domain, or coordinates","description":"Unified facility search. Provide at least one of: non-empty **`name`**, non-empty **`address`**, **`zip_code`**, non-empty **`website_domain`**, or both **`city`** and **`state`** (then use **`radius`** around the geocoded point). You may also pass **`location`** as `latitude,longitude` for radius search instead of city/state.\nOptionally include lane data per facility with **`include_lanes=true`**. Lanes can be filtered by **`min_distance`** (miles from facility) and **`direction`** (compass direction). Filters are applied before the **`top_n`** limit.\n\n## Pagination\n\nWhen results exceed 100 facilities, the response is paginated using opaque cursor-based pagination. The `Link` response header contains a next-page URL with a `cursor` parameter. Follow that URL to retrieve subsequent pages. The `X-Total-Count` header shows the total matching facilities across all pages. Pagination is not supported with `smart_search=true`.\nSee component schema **FacilitiesQueryCriteria** for the full parameter model and validation shape.\nHistorical path `/find_facilities` exposes the same search behavior and is documented here as **`/facilities`** for a single contract.\n","parameters":[{"name":"accept","in":"header","required":true,"schema":{"type":"string"},"description":"application/json"},{"name":"Access-Token","in":"header","required":true,"schema":{"type":"string"},"description":"Access Token for authentication"},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"X api key for authentication"},{"description":"Facility or collection name (optional if `address`, both `city` and `state`, or `website_domain` are provided).\nSee **FacilitiesQueryCriteria** for validation rules.\n","in":"query","name":"name","required":false,"schema":{"type":"string","maxLength":500}},{"description":"Substring match on formatted address (optional if `name`, both `city` and `state`, or `website_domain` are provided).\n","in":"query","name":"address","required":false,"schema":{"type":"string","maxLength":500}},{"description":"City; use with `state` for geocoded radius search unless `name`, `address`, or `website_domain` alone is sufficient.","in":"query","name":"city","required":false,"schema":{"type":"string","maxLength":150}},{"description":"State; use with `city` unless `name`, `address`, or `website_domain` supplies the search mode.","in":"query","name":"state","required":false,"schema":{"type":"string","maxLength":150}},{"description":"Substring match against the shipper's `contact_url`. Must include the TLD\n(e.g. `acme.com`). Optional path tails (`acme.com/about`) are accepted by\nthe validator but the path is stripped before matching — only the host\nis searched.\n\n**Mutually exclusive with `name` and `address`.** If `name` or `address`\nis also supplied, `website_domain` is silently ignored (see\n**FacilitiesQueryCriteria** → *Filter precedence*). Also ignored when\n`smart_search=true` is used together with `name`.\n","in":"query","name":"website_domain","required":false,"schema":{"type":"string","maxLength":253,"minLength":5,"pattern":"^[A-Za-z0-9][A-Za-z0-9-]*\\.[A-Za-z]{2,}([/.].*)?$"}},{"description":"Comma-separated `latitude,longitude`; radius applies around this point when provided instead of city/state.","in":"query","name":"location","required":false,"schema":{"type":"string"}},{"description":"Search radius in miles around the geocoded city/state point or `location`","in":"query","name":"radius","required":false,"schema":{"type":"number","maximum":150}},{"description":"Lot size category filter","in":"query","name":"lot_size_category","required":false,"schema":{"type":"string","maxLength":50}},{"description":"Maximum number of facilities to return","in":"query","name":"limit","required":false,"schema":{"type":"integer"}},{"description":"Optional place category filter (pipe-separated values accepted by the service)","in":"query","name":"facility_type","required":false,"schema":{"type":"string","maxLength":500}},{"description":"Optional intermodal drayage filter flag","in":"query","name":"intermodal_drayage","required":false,"schema":{"type":"string"}},{"description":"Include inbound and outbound lane data for each facility. Lanes are ranked by weight.","in":"query","name":"include_lanes","required":false,"schema":{"type":"boolean"}},{"description":"Number of top lanes to return per direction (inbound/outbound) per facility.","in":"query","name":"top_n","required":false,"schema":{"type":"integer","default":10}},{"description":"Minimum distance in miles from the facility to a lane destination. Lanes closer than this distance are excluded. Applied before top_n.","in":"query","name":"min_distance","required":false,"schema":{"type":"number"}},{"description":"Filter lanes by compass direction from the facility. Applied before top_n.","in":"query","name":"direction","required":false,"schema":{"type":"string","enum":["N","S","E","W","NE","NW","SE","SW"]}},{"description":"US zip code; searches facilities near the zip centroid.","in":"query","name":"zip_code","required":false,"schema":{"type":"string"}},{"description":"Opaque pagination cursor from the Link header of a previous response.\nWhen results exceed 100 facilities, the server returns a Link header\ncontaining a next-page URL with this cursor embedded. Follow that URL\nto retrieve subsequent pages. Do not construct or parse this value —\nit is server-controlled and opaque.\n","in":"query","name":"cursor","required":false,"schema":{"type":"string","maxLength":500}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","description":"Array of facility objects (see FacilitiesQueryCriteria for query rules).","items":{"$ref":"#/components/schemas/Facility"}}}},"description":"List of facilities","headers":{"X-Total-Count":{"description":"Total number of matching facilities across all pages.","schema":{"type":"integer"}},"Link":{"description":"RFC 8288 Link header with rel=\"next\" pointing to the next page URL.\nAbsent on the final page. Example:\n`<https://api.genlogs.io/find_facilities?zip_code=91761&include_lanes=true&cursor=eyJ...>; rel=\"next\"`\n","schema":{"type":"string"}}}},"400":{"description":"Validation error (missing search criteria, invalid parameters, or invalid cursor)"}}}}},"components":{"schemas":{"Facility":{"properties":{"contact_phone":{"nullable":true,"type":"string"},"contact_url":{"nullable":true,"type":"string"},"facility_name":{"type":"string"},"formatted_address":{"type":"string"},"id":{"type":"string"},"lat":{"type":"number"},"lon":{"type":"number"},"operating_hours":{"nullable":true,"type":"string"},"place_category":{"type":"string"},"equipment_pairings":{"type":"array","nullable":true,"description":"Equipment types paired with this facility based on observed carrier activity. Values are Title Case display strings (e.g. \"Dry Van\", \"Box Truck\", \"Reefer\"). Empty array when no pairing data is available.\n","items":{"type":"string"}},"inbound_lanes":{"type":"array","description":"Top inbound lanes ranked by weight (only present when `include_lanes=true`).","items":{"$ref":"#/components/schemas/FacilityLane"}},"outbound_lanes":{"type":"array","description":"Top outbound lanes ranked by weight (only present when `include_lanes=true`).","items":{"$ref":"#/components/schemas/FacilityLane"}}},"required":["facility_name","formatted_address","id","lat","lon","place_category"],"type":"object"},"FacilityLane":{"type":"object","properties":{"city":{"type":"string","description":"Largest city in the H3 hexagon."},"state":{"type":"string","description":"US state of the lane destination."},"weight":{"type":"number","description":"Ranking signal from the network GeoJSON (higher = stronger lane)."},"visit_share":{"type":"string","description":"Bucketed visit share percentage (e.g. \"15-20%\")."},"hexagon_id":{"type":"string","description":"H3 hexagon index for the lane destination."},"distance_miles":{"type":"number","nullable":true,"description":"Distance in miles from the facility to the lane destination (present when min_distance or direction is provided)."},"direction":{"type":"string","nullable":true,"description":"Compass direction of the lane from the facility (e.g. \"NE\", \"SW\"). Present when min_distance or direction filter is provided."}},"required":["city","state","weight","visit_share","hexagon_id"]}}}}
```
