# Genlogs API Docs

## Welcome to GenLogs!

GenLogs API is designed to provide a robust and scalable solution for all your integration needs. This documentation will guide you through the setup, authentication, and usage of the API, along with detailed explanations of the available endpoints.

#### Features

* Source Carriers by Lane: Discover carriers operating on a specified lane&#x20;
* Source Shippers by Lane: Discover shippers operating on a specified lane
* Source Shippers by Region: Discover shippers operating in a specified region
* And much more


# Getting started

To start using the GenLogs API, follow these steps:

**1. Get Your APi key and Credentials**

Genlogs Customer success team members will set up your account and will share with you and api key and user/password credentials.

Once you get the api and credentials, you would be able to make a http request to the Create Token endpoint, from it you will get a ***token***

When the token is generated you can proceed to call carrier or shipper endpoints sending both, the api ***key*** and the api ***token***&#x20;


# Verify

Verify if a carrier has been observed within 150 miles of an origin, destination, or along the lane within the last 90 days.&#x20;

This information can help to mitigate fraud and ensure accurate capacity claims during the carrier vetting process.

### **Logic**

Check to see if a carrier has been observed within 150 miles of an

1. Origin
2. Destination
3. Or along the lane in between

If any of the three checks are true, then the carrier is verified. GenLogs uses sensor data to confirm carrier locations along with other third party data sets.

{% hint style="info" %}
Note: It is generally recommended to 'reward' carriers when verified is true but not to 'penalize' them when verified is false.&#x20;
{% endhint %}

### **Authentication**

&#x20;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

The `verifier-carrier` permission is required to access this endpoint.

### Endpoint

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

### Query Parameters

* **usdot** (string, Required):  usdot of the detected carrier.
* **origin\_city** (string, Required): Name of the city of the starting location.
* **origin\_state** (string, Required): Name of the state of the starting location.
* **destination\_city** (string, Optional): Name of the city of the destination location.
* **destination\_state** (string, Optional): Name of the state of the destination location.

### **Response**

* **200 OK:** A JSON object containing the message verified true or false
* **400 Bad Request:** If required parameters are missing or invalid.
* **401 Unauthorized:** If the authentication credentials (email and password) are missing or incorrect.
* **403 Forbidden**:  Access to the requested resource is forbidden.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

* verified (boolean): true or false

### Request Example:

```
curl -X GET 'https://api.genlogs.io/visual_sightings/verify?usdot=2523551&origin_state=Georgia&origin_city=Tucker' \
-H 'Access-Token: {access_token}' \
-H 'x-api-key: {your_api_key}' \
-i
```

{% openapi src="/files/lR4zyQ7rTBeVsmake7qP" path="/verify" method="get" %}
[Broken mention](broken://files/lR4zyQ7rTBeVsmake7qP)
{% endopenapi %}


# Pagination

## Overview

Some Genlogs API endpoints return large result sets that are split across multiple pages. When this happens, the API returns a subset of results along with pagination headers that allow you to retrieve the remaining pages.

Pagination is currently available on the following endpoints:

<table><thead><tr><th width="202.71484375">Endpoint</th><th width="249.3203125">Paginated when</th><th>Page Size</th></tr></thead><tbody><tr><td><a href="/shipper/shipper-facilities">GET /facilities</a></td><td>include_lanes=true</td><td>20</td></tr></tbody></table>

*This page will be updated as pagination support is added to additional endpoints.*

## Navigating pages with the <kbd>Link</kbd> header

Paginated responses include a <kbd>Link</kbd> header containing URLs for navigating between pages. If all results fit on a single page, the Link header is omitted.

A typical Link header looks like this:

```shellscript
Link: <https://api.genlogs.io/facilities?zip_code=91761&include_lan
  es=true&cursor=eyJ0b3...>; rel="next"
```

The following relationships may appear:

<table><thead><tr><th width="209.18359375">Relationships</th><th>Meaning</th></tr></thead><tbody><tr><td>rel="next"</td><td>URL for the next page of results</td></tr><tr><td>rel="prev"</td><td>URL for the previous page of results</td></tr></tbody></table>

<kbd>rel="next"</kbd> is absent on the final page. <kbd>rel="prev"</kbd> is absent on the first page.

To retrieve the next page, make a request to the URL provided in the Link header. The URL includes all original query parameters along with a cursor value, there is no need to rebuild the request.

## Tracking total results with <kbd>X-Total-Count</kbd>

Every paginated response includes an X-Total-Count header with the total number of matching results across all pages. This can be used for progress indicators or to determine how many pages to expect.

<kbd>X-Total-Count</kbd>: 999

This value is consistent across all pages of a result set.

## Inspecting pagination headers

To verify pagination is working, you can inspect response headers using curl:

```shellscript
curl --include \
--url "https://api.genlogs.io/facilities?zip_code=91761&include_lanes=true" \           
--header "Access-Token: [your-token]" \           
--header "x-api-key: [your-api-key]" \
```

The --include flag prints the response headers above the body, allowing you to see the Link and X-Total-Count values.

You can use the URLs from the Link header to request another page of results. For example, to request the next page based on the previous example:

```shellscript
curl --include --request GET \
--url "https://api.genlogs.io/facilities?zip_code=91761&include_lanes=true&cursor=eyJ0b3..." \
--header "Access-Token: [your-token]" \
--header "x-api-key: [your-api-key]" \
```

The URLs in the Link header include the cursor query parameter, which the server uses to determine which page to return. The cursor value is opaque, do not attempt to parse, modify, or construct it. Always use the complete URL provided in the Link header.

## Iterating through pages programmatically

### Python

The requests library parses the <kbd>Link</kbd> header automatically via response.links. The following script collects all facilities across every page:

```python
import requests                                                                                
                                                      
  BASE_URL = "https://api.genlogs.io"                                                            
  headers = {                                         
      "Access-Token": "<your-token>",
      "x-api-key": "<your-api-key>",
  }                                           
                                          
  url = f"{BASE_URL}/facilities?zip_code=91761&include_lanes=true"
  facilities = []                                                                                
   
  while url:                                                                                     
      response = requests.get(url, headers=headers)   
      response.raise_for_status()
      facilities.extend(response.json())
      url = response.links.get("next", {}).get("url")
                                          
  total = response.headers.get("X-Total-Count")
  print(f"Fetched {len(facilities)} of {total} facilities")
```

### Javascript

```python
const headers = {                                                                              
    "Access-Token": "<your-token>",
    "x-api-key": "<your-api-key>",                                                               
  };                                                  

  let url = "https://api.genlogs.io/facilities?zip_code=91761&include_lanes=true";
  const facilities = [];                  
  let lastResponse;
                                                                                                 
  while (url) {
    lastResponse = await fetch(url, { headers });                                                
    const data = await lastResponse.json();           
    facilities.push(...data);             

    const linkHeader = lastResponse.headers.get("Link") || "";                                   
    const match = linkHeader.match(/<([^>]+)>;\s*rel="next"/);
    url = match ? match[1] : null;                                                               
  }                                                   

  const total = lastResponse.headers.get("X-Total-Count");                                       
  console.log(`Fetched ${facilities.length} of ${total} facilities`);
```

## Things to know:

* Cursor values are opaque. Do not parse, modify, cache long-term, or construct cursor values. Always follow the URL provided in the Link header.
* Authentication is required on every page request. Include your Access-Token and x-api-key headers on each request, including subsequent pages.
* Cursors do not expire. You can pause between page requests without losing your position in the result set.
* All query filters are preserved. The server embeds your original query parameters (zip\_code, include\_lanes, etc.) in the Link URL. You do not need to re-supply them.
* Backwards compatible. Requests that do not include a cursor parameter behave exactly as before. Existing integrations require no changes.
* Not supported with smart search. Combining the cursor parameter with <kbd>smart\_search=true</kbd> returns a 400 Bad Request error.


# Create token

### **Create Access Token**

The "Create Access Token" endpoint allows a user to generate new access and refresh tokens by providing their email and password. These tokens are essential for authenticating and authorizing API requests.

### **Authentication**

* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### **Endpoint**

* **URL**: [`https://api.genlogs.io/auth/token`](#create-access-token)
* **Method**: `POST`

### **Request Parameters**

Credentials must be provided in the JSON request body.

#### Recommended: JSON request body

Send `email` and `password` in a JSON body with the `Content-Type: application/json` header. No URL-encoding of special characters is needed (e.g. `1234+` can be sent as-is).

```json
curl -X POST 'https://api.genlogs.io/auth/token/'
-H 'accept: application/json'
-H 'Content-Type: application/json'
-H 'x-api-key: {your_api_key}'
-d '{"email": "{email}", "password": "{password}"}'
```

Body schema:

```json
{ "email": "user@example.com", "password": "your_password" }
```

#### Parameters

* `email` (string, required): The email address of the user requesting the tokens.
* `password` (string, required): The password of the user for authentication.

### **Response**

* **200 OK**: Successfully generated and returned the access and refresh tokens.
* **401 Unauthorized**: If the provided email, and password, resulting in a failure to create the tokens.
* **500 Internal Server Error**: If an error occurs on the server during token creation.

### **Response Body**

{% hint style="info" %}
Note: The refresh token is not usable at this time. Please create a new token after your original access token has expired
{% endhint %}

* **access\_token\_data** (TokenSchema): The schema representing the access token and its expiration.
  * **token** (string): The access token string used for authentication and authorization.
  * **expires** (datetime): The datetime when the access token expires.
* **refresh\_token\_data** (TokenSchema): The schema representing the refresh token and its expiration.
  * **token** (string): The refresh token string used to obtain a new access token.
  * **expires** (datetime): The datetime when the refresh token expires.
* **user\_id** (int): The ID of the user for whom the tokens were created.
* **company\_id** (int): The ID of the company associated with the authenticated user.
* **customer\_name** (string): The name of the customer associated with the authenticated user.

### Request Example:

```sh
curl -X POST 'https://api.genlogs.io/auth/token/' \
  -H 'accept: application/json' \
  -H 'content-type: application/json' \
  -H 'x-api-key: {your_api_key}' \
  -d '{
    "email": "{email}",
    "password": "{password}"
  }'
```

## Create access and refresh tokens

> Create and return new access and refresh tokens for a user based on their email and password. Send credentials in the JSON request body. Query parameters are deprecated and will be removed on September 30, 2026; when they are used, the response includes Deprecation, Sunset, and Link headers.

```json
{"openapi":"3.0.3","info":{"title":"Auth API - Create Token","version":"1.0.0"},"servers":[{"url":"https://api.genlogs.io","description":"GenLogs API"}],"paths":{"/auth/token":{"post":{"tags":["auth"],"summary":"Create access and refresh tokens","description":"Create and return new access and refresh tokens for a user based on their email and password. Send credentials in the JSON request body. Query parameters are deprecated and will be removed on September 30, 2026; when they are used, the response includes Deprecation, Sunset, and Link headers.","operationId":"createAccessToken","parameters":[{"name":"email","in":"query","required":false,"deprecated":true,"schema":{"type":"string","format":"email"},"description":"Deprecated. Email of the user requesting tokens. Use the JSON request body instead. Query-parameter credentials will be removed on September 30, 2026."},{"name":"password","in":"query","required":false,"deprecated":true,"schema":{"type":"string","format":"password"},"description":"Deprecated. Password of the user requesting tokens. Use the JSON request body instead. Query-parameter credentials will be removed on September 30, 2026."}],"requestBody":{"required":false,"description":"JSON credentials (preferred). When both a body and query parameters are provided, the body takes precedence.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTokenBody"}}}},"responses":{"200":{"description":"Access and refresh tokens created successfully.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthSchema"}}}},"400":{"description":"Token creation failed because email or password is missing.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}}}},"401":{"description":"Token creation failed because credentials are invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPError"}}}},"422":{"description":"Request validation error, including empty email or password.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"CreateTokenBody":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email","description":"Email of the user requesting tokens."},"password":{"type":"string","format":"password","description":"Password of the user requesting tokens."}}},"AuthSchema":{"type":"object","required":["access_token_data","refresh_token_data","user_id"],"properties":{"access_token_data":{"$ref":"#/components/schemas/TokenSchema"},"refresh_token_data":{"$ref":"#/components/schemas/TokenSchema"},"user_id":{"type":"integer"},"company_id":{"type":"integer","nullable":true},"customer_name":{"type":"string","nullable":true}}},"TokenSchema":{"type":"object","required":["token","expires"],"properties":{"token":{"type":"string"},"expires":{"type":"string","format":"date-time"}}},"HTTPError":{"type":"object","properties":{"detail":{"type":"string"}}},"HTTPValidationError":{"type":"object","properties":{"detail":{"type":"array","items":{"$ref":"#/components/schemas/ValidationError"}}}},"ValidationError":{"type":"object","required":["loc","msg","type"],"properties":{"loc":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"integer"}]}},"msg":{"type":"string"},"type":{"type":"string"}}}}}}
```


# Refresh token

### **Refresh Token**

The "Refresh Token" endpoint allows a user to generate new access and refresh tokens by providing  a valid refresh token. These  tokens are essential for authenticating and authorizing API requests.

### **Authentication**

* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### **Endpoint**

* **URL**: [`https://api.genlogs.io/auth/token/refresh`](#refresh-token)
* **Method**: `POST`

### **Request Parameters**

* **refresh\_token** (string, required): The previously created valid refresh token.

### **Response**

* **200 OK**: Successfully generated and returned the access and refresh tokens.
* **401 Unauthorized**: If the provided email, and password, resulting in a failure to create the tokens.
* **500 Internal Server Error**: If an error occurs on the server during token creation.

### **Response Body**

* **access\_token\_data** (`TokenSchema`): The schema representing the access token and its expiration.
  * **token** (string): The access token string used for authentication or authorization.
  * **expires** (datetime): The datetime when the access token will expire.
* **refresh\_token\_data** (`TokenSchema`): The schema representing the refresh token and its expiration.
  * **token** (string): The refresh token string used for obtaining a new access token.
  * **expires** (datetime): The datetime when the refresh token will expire.
* **user\_id** (string): The ID of the user for whom the tokens were created.

### Request Example:

```sh
curl -X POST 'https://api.genlogs.io/auth/token/refresh?refresh_token={refresh_token}' \
-H 'accept: application/json' \
-H 'x-api-key: {your_api_key}'
```

## POST /token/refresh

> Get the AccessToken And Refresh Token

```json
{"openapi":"3.1.0","info":{"title":"Refresh token API","version":"1.0.0"},"servers":[{"url":"https://api.genlogs.io/auth"}],"paths":{"/token/refresh":{"post":{"tags":["auth"],"summary":"Get the AccessToken And Refresh Token","operationId":"refresh_token_get","parameters":[{"name":"accept","in":"header","required":true,"schema":{"type":"string","default":"application/json"},"description":"Specifies the format of the response."},{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"API key for authentication"},{"name":"refresh_token","in":"query","required":true,"schema":{"type":"string","description":"The previously created valid refresh token","title":"Refresh token"},"description":"The previously created valid refresh token"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"AuthenticationResponse":{"properties":{"access_token_data":{"items":{"$ref":"#/components/schemas/AccessTokenSchema"},"type":"object","title":"access_token_data"},"refresh_token_data":{"items":{"$ref":"#/components/schemas/RefreshTokenSchema"},"type":"object","title":"refresh_token_data"},"user_id":{"type":"string","title":"user_id"},"company_id":{"type":"integer","title":"company_id"}},"type":"object","required":["access_token_data","refresh_token_data","user_id","company_id"],"title":"AuthenticationResponse"},"AccessTokenSchema":{"properties":{"token":{"type":"string","title":"Token"},"expires":{"type":"string","title":"expires"}},"type":"object","required":["token","expires"],"title":"AccessTokenSchema"},"RefreshTokenSchema":{"properties":{"token":{"type":"string","title":"Token"},"expires":{"type":"string","title":"expires"}},"type":"object","required":["token","expires"],"title":"AccessTokenSchema"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}
```


# Carrier Recommendations

### Carrier Recommendations Endpoint&#x20;

Retrieve a list of recommended carriers operating near an origin, destination, or on a specified lane.&#x20;

### **Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### Permissions

The `external-api-carrier-recommendation` permission is required to access this endpoint.

### **Endpoint**

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

### **Headers**

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

### **Query Parameters:**

{% hint style="info" %}
The GenLogs **`carrier_score`** indicates the likelihood of a carrier meeting the specific needs of a given search query. It is a composite score based on a blend of lane, equipment, and company match factors.

* Lane Factors (lane\_score): Likelihood to be seen at an origin, destination, or along a lane (O/D pairing)

* Equipment Factors (equipment\_type\_score): Likelihood to have the requested equipment type

* Company factors (company\_score): compliance, safety, maintenance, and insurance metrics
  {% endhint %}

* [**origin\_city** (string, optional): Name of the origin city. Note that townships and counties are not accepted.](#user-content-fn-1)[^1]

* [**origin\_state** (string, optional): Full name or two-letter abbreviation of the origin state.](#user-content-fn-1)[^1]

* [**destination\_city** (string, optional): Name of the destination city. Note that townships and counties are not accepted.](#user-content-fn-1)[^1]

* [**destination\_state** (string, optional): Full name or two-letter abbreviation of the destination state.](#user-content-fn-1)[^1]

* **origin\_radius** (int, optional): Radius (miles) around the origin location for carrier search - default 50 miles (max. 100 miles).

* **destination\_radius** (int, optional): Radius (miles) around the destination location for carrier search - default 50 miles (max. 100 miles).

* **carrier\_score\_min** (float, optional): Minimum acceptable carrier score - default to 0.
  * Accepts values between 0 and 1

* **carrier\_score\_max** (float, optional): Maximum acceptable carrier score - default to 1
  * Accepts values between 0 and 1. Generally, we recommend omitting this parameter

* **fleet\_size\_min** (number, optional): Minimum fleet size of carriers - default 0 power units

* **fleet\_size\_max** (number, optional): Maximum fleet size of carriers - default 1000 power units

* **preferred\_carriers:** (boolean, optional): Only return carriers that match your Onboarded Carrier list, as configured in the web application.

* **auth\_months\_min** (number, optional, default=1): Minimum number of months a carrier has an active common or contract authority with FMCSA

* **power\_only** (boolean, optional):  Filters carriers that operate tractors without owning trailers.

* **broker\_authority** (boolean, optional):  Filters carriers that also have a brokerage arm.

* **is\_possible\_backhaul** (boolean, optional): Filters to only return carriers where the specified lane is a possible backhaul based on their domicile address proximity to the destination.

* **carried\_cargo** (string, optional): Type of cargo registered to carried., Possible values:&#x20;

<details>

<summary>Carried Cargo options: </summary>

* Passengers&#x20;
* Garbage/Refuse&#x20;
* Mobile Homes&#x20;
* Drive/Tow away&#x20;
* Water Well&#x20;
* Livestock&#x20;
* Utilities&#x20;
* Agricultural/Farm Supplies&#x20;
* General Freight&#x20;
* Household Goods&#x20;
* US Mail&#x20;
* Beverages&#x20;
* Paper Products&#x20;
* Fresh Produce&#x20;
* Meat&#x20;
* Refrigerated Food
* Metal: sheets, coils rolls
* Logs, Poles, Beams, Lumber&#x20;
* Building Materials&#x20;
* Machinery, Large Objects&#x20;
* Oilfield Equipment&#x20;
* Construction&#x20;
* Liquids/Gases&#x20;
* Chemicals&#x20;
* Motor Vehicles&#x20;
* Grain Feed Hay&#x20;
* Coal/Coke&#x20;
* Commodities Dry Bulk&#x20;
* Intermodal Cont.

</details>

* **equipment\_types** (case sensitive string, optional): A list of equipment types and subtypes used by the carrier. You may list multiple values using a pipe (“|”) delimiter. You can specify a subtype by naming the parent class and child class separated by a colon. The scheme is Type 1: Subtype 1 | Type 2: Subtype 2 | Type 3: Subtype 3.
  * Examples:
    * equipment\_types: Dry Van | Box Truck
    * equipment\_types: Dry Van: Double Pup | Box Truck | Flatbed: Step deck | Flatbed: Lowboy RGN

<details>

<summary>Equipment type options</summary>

| Equipment Type | Subtype (Optional)   |
| -------------- | -------------------- |
| Dry Van        | Moffett              |
| Dry Van        | Drop Frame           |
| Dry Van        | Double Pup           |
| Reefer         | Moffett              |
| Flatbed        | Step Deck            |
| Flatbed        | Moffett              |
| Flatbed        | Lowboy RGN           |
| Flatbed        | Logging              |
| Flatbed        | Gooseneck            |
| Flatbed        | Conestoga            |
| Flatbed        | Air Ride             |
| Flatbed        | 53 Ft Flatbed        |
| Box Truck      |                      |
| Car Hauler     | Gooseneck            |
| Dry Bulk       | Hopper               |
| Dry Bulk       | Air Ride             |
| Dry Bulk       | Agricultural         |
| Dump           | Side Dump            |
| Dump           | Open Top             |
| Dump           | End Dump             |
| Dump           | Belly Dump           |
| Intermodal     | Gooseneck            |
| Power Unit     | Sleeper Cab          |
| Power Unit     | Day Cab              |
| Tanker         | Vacuum Tank          |
| Tanker         | Steel                |
| Tanker         | Cryogenic            |
| Tanker         | Compressed Gas       |
| Tanker         | Chemical             |
| Tanker         | Aluminum             |
| Other          | Wrecker              |
| Other          | Livestock Trailer    |
| Other          | High Tonnage Trailer |

</details>

* **preferred\_carriers:** (boolean, optional): Only return carriers marked as preferred.
* **auth\_months\_min** (float, optional, default=1.0): Minimum number of months a carrier has an active common or contract authority with FMCSA
* **power\_only** (boolean, optional):  Filters carriers that operate tractors without owning trailers.
* **broker\_authority** (boolean, optional): Filters carriers that have an active broker authority or not.

### Search Tips&#x20;

#### **Perform and origin- or destination-only search**

**Origin-only search**

* Provide `origin_city` and `origin_state`.
* You no longer need to include `destination_city` or `destination_state` as `null`.
* You may omit `destination_radius` if it is not relevant.

**Destination-only search**

* Provide `destination_city` and `destination_state`.
* You no longer need to include `origin_city` or `origin_state` as `null`.
* You may omit `origin_radius` if it is not relevant.

**General rule**

Origin-only and destination-only searches are valid. You do **not** need to send all four parameters at the same time, and you no longer need to provide the unused city/state pair with `null` values.

{% hint style="info" %}
*Note: If you receive a bad request, make sure to omit the **origin\_radius** or **destination\_radius** field.*
{% endhint %}

#### Understanding contact information

**Carrier Recommendations returns two sets of contact information: Onboarded Carrier fields and FMCSA fields.**

* Onboarded Carrier fields: these values are provided by your Onboarded Carrier list, which admins can update in our UI. If no values are uploaded, they will be blank.
  * contact\_email
  * contact\_name
  * contact\_phone
* FMCSA fields: these contact values are provided from the FMCSA. They are shown exactly as registered, including possible null values, multiple semicolon separated values, or values with typos.
  * telephone
  * email\_address

### **Response:**

* **200 OK:** A JSON object containing recommendations and lane volume details.
* **400 Bad Request:** If required parameters are missing or invalid.
* **401 Unauthorized:** If the authentication credentials (email and password) are missing or incorrect.
* **403 Forbidden**:  Access to the requested resource is forbidden.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

* **recommendations** (array of `CarrierRecommendation` objects): List of recommended carriers.
  * **add\_date** (string): Date the recommendation was added.
  * **auth\_months** (number): Duration of the carrier’s authority in months.
  * **authorized\_for\_hire** (string): Indicates if the carrier is authorized for hire (Y/N).
  * **bipd\_insurance\_on\_file** (number): Amount of Bodily Injury and Property Damage insurance on file (in US dollars).
  * **broker\_authority\_status** (string): Indicates if the carrier has broker authority status
    * A = Holds Active Authority&#x20;
    * I = Inactive Authority&#x20;
    * N = No Authority
  * **cargo\_insurance\_on\_file** (number): Amount of cargo insurance on file (in US dollars).
  * **carried\_cargo** (string): Type of cargo carried by the carrier.
  * **carrier\_assessment** (string): Assessment or notes about the carrier.
  * **carrier\_driver\_oos\_rate** (number): Carrier’s driver Out-of-Service (OOS) rate.
  * **carrier\_driver\_oos\_rate\_national\_avg** (number): National average OOS rate for drivers.
  * **carrier\_ein** (number): Employer Identification Number (EIN) of the carrier.
  * **carrier\_score** (number): GenLogs proprietary carrier match score, incidating the likelihood of a carrier meeting the specific needs of a given search query. **Carrier\_score** is composed of **company\_score**, **equipment\_type\_score**, and **lane\_score**.
  * **carrier\_score\_scaled** (number): The carrier\_score on a scaled basis, with the best carrier for the lane scaling to 100%. Note that this is the score shown in our UI.
  * **carrier\_total\_power\_units** (number): Total power units operated by the carrier.
  * **carrier\_vehicle\_oos\_rate** (number): Carrier’s vehicle OOS rate.
  * **carrier\_vehicle\_oos\_rate\_national\_avg** (number): National average OOS rate for vehicles.
  * **classdef** (string): Classification of the carrier’s operation.
  * **company\_score** (number): Score representing the carrier’s company performance or reliability.
  * **confirmed\_email** (object): List of available emails.
    * ```json
      {
          "safety@zipzap-logistics.com": {
              "add_date": "2025-09-29"
          },
          "safety2@zipzap-logistics.com": {
              "add_date": "2025-09-29"
          },
          ...
      }
      ```
  * **confirmed\_phone** (object): List of available phone numbers.
    * ```json
      {
          "1-619-963-1591": {
              "add_date": "2025-09-29"
          },
          "1-123-456-7890": {
              "add_date": "2025-09-29"
          },
          ...
      }
      ```
  * **contact\_email** (string): Email address of the carrier, provided by your Onboarded Carrier upload.
  * **contact\_name** (string): Contact name of the carrier, provided by your Onboarded Carrier upload.
  * **contact\_phone** (string): Phone number of the carrier, provided by your Onboarded Carrier upload.
  * **dba\_name** (nullable string): Doing Business As (DBA) name of the carrier.
  * **dot\_number** (string): DOT number of the carrier.
  * **driver\_total** (number): Total number of drivers employed by the carrier.
  * **email\_address** (string): FMCSA listed email address.
  * **equipment\_type\_score** (number): Score representing the suitability of the carrier’s equipment types.
  * **equipment\_types** (string): Types of equipment operated by the carrier.
  * **exempt\_for\_hire** (string): Indicates if the carrier is exempt from for-hire regulations (Y/N).
  * **federal\_government** (string): Indicates if the carrier is a federal government entity (Y/N).
  * **indian\_tribe** (string): Indicates if the carrier is an Indian tribe entity (Y/N).
  * **is\_possible\_backhaul** (boolean): Indicates if the specified lane is a possible backhaul for the carrier based on their domicile address.
  * **is\_power\_only** (boolean): Carriers that operate tractors without owning trailers according to FMCSA records.
  * **is\_preferred** (boolean): Whether the carrier has been marked as preferred or not.
  * **is\_visually\_sighted** (boolean): Whether the carrier has been visually sighted.
  * **lane\_score** (number): Score representing the suitability of the carrier for a specific lane.
  * **lat** (nullable number): Latitude of the FMCSA registered address.
  * **legal\_name** (string): Legal name of the carrier.
  * **local\_government** (string): Indicates if the carrier is a local government entity (Y/N).
  * **lon** (nullable number): Longitude of the FMCSA registered address.
  * **mc\_number** (number): Motor Carrier (MC) number of the carrier.
  * **mcs150\_date** (string): Date of the carrier’s MCS-150 form submission.
  * **mcs150\_mileage** (number): Annual mileage reported on the carrier’s MCS-150 form.
  * **mcs150\_mileage\_year** (number): Year of the mileage reported on the carrier’s MCS-150 form.
  * **migrant** (string): Indicates if the carrier transports migrant workers (Y/N).
  * **name** (string): Name of the carrier, often matching the legal name.
  * **op\_other** (string): Indicates if the carrier has other operational classifications (Y/N).
  * **operation\_classification** (string): Classification of the carrier’s operational authority according to the FMCSA (e.g. AUTHORIZED FOR HIRE).
  * **phy\_city** (string): City of the carrier's domicile address.
  * **phy\_state** (string): State of the carrier's domicile address.
  * **phy\_street** (string): Street address of the carrier's domicile address.
  * **phy\_zip** (string): City of the carrier's domicile address.
  * **private\_only** (string): Carriers that are not for-hire, whose authority is solely for their own commercial enterprise, not available to the public at large (Y/N).
  * **private\_passenger\_business** (string): Indicates if the carrier transports private passengers for business (Y/N).
  * **private\_passenger\_nonbusiness** (string): Indicates if the carrier transports private passengers for non-business purposes (Y/N).
  * **private\_property** (string): Indicates if the carrier transports private property (Y/N).
  * **state\_government** (string): Indicates if the carrier is a state government entity (Y/N).
  * **telephone** (string): FMCSA listed telephone number.
  * **us\_mail** (string): Indicates if the carrier transports U.S. mail (Y/N).

### Request Example:

## GET /carrier/recommendations

> Get carrier recommendations based on location

```json
{"openapi":"3.0.2","info":{"title":"Carrier API","version":"1.0.1"},"servers":[{"url":"https://api.genlogs.io"}],"paths":{"/carrier/recommendations":{"get":{"parameters":[{"name":"accept","in":"header","required":true,"schema":{"type":"string","default":"application/json"},"description":"Specifies the format of the response."},{"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":"API key for authentication"},{"in":"query","name":"origin_city","required":true,"schema":{"type":"string","default":"Nashville"},"description":"Origin city for the recommendation"},{"in":"query","name":"origin_state","required":true,"schema":{"type":"string","default":"TN"},"description":"Origin state for the recommendation"},{"in":"query","name":"destination_city","required":true,"schema":{"type":"string","default":"Dallas"},"description":"Destination city for the recommendation"},{"in":"query","name":"destination_state","required":true,"schema":{"type":"string","default":"TX"},"description":"Destination state for the recommendation"},{"default":50,"in":"query","name":"origin_radius","schema":{"type":"number","default":50},"description":"Search radius around the origin location in miles"},{"default":50,"in":"query","name":"destination_radius","schema":{"type":"number","default":50},"description":"Search radius around the destination location in miles"},{"default":0,"in":"query","name":"carrier_score_min","schema":{"type":"float","default":0},"description":"Minimum carrier score"},{"default":100,"in":"query","name":"carrier_score_max","schema":{"type":"float","default":1},"description":"Maximum carrier score"},{"default":"None","in":"query","name":"fleet_size_min","schema":{"type":"number"},"description":"Minimum fleet size"},{"default":"None","in":"query","name":"fleet_size_max","schema":{"type":"number"},"description":"Maximum fleet size"},{"in":"query","name":"carried_cargo","schema":{"type":"string","default":"general goods"},"description":"Type of cargo carried"},{"in":"query","name":"equipment_types","schema":{"type":"string","default":"flatbed"},"description":"Type of equipment used by carriers"},{"in":"query","name":"preferred_carriers","schema":{"type":"boolean","default":false},"description":"Filter for preferred carriers"},{"in":"query","name":"real_time","schema":{"type":"boolean","default":false},"description":"Request real-time data if available"},{"in":"query","name":"auth_months_min","schema":{"type":"number","default":1},"description":"Minimum number of months a carrier has an active common or contract authority with FMCSA"},{"in":"query","name":"power_only","schema":{"type":"boolean","default":false}},{"in":"query","name":"broker_authority","schema":{"type":"boolean","default":false}},{"in":"query","name":"is_possible_backhaul","schema":{"type":"boolean","default":false}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CarrierResponse"}}},"description":"The JSON response containing recommendations and lane volume"}},"summary":"Get carrier recommendations based on location"}}},"components":{"schemas":{"CarrierResponse":{"properties":{"real_time_locs":{"items":{"$ref":"#/components/schemas/CarrierRealTimeLocs"},"type":"array"},"recommendations":{"items":{"$ref":"#/components/schemas/CarrierRecommendation"},"type":"array"}},"required":["real_time_locs","recommendations"],"type":"object"},"CarrierRealTimeLocs":{"properties":{"current_lat":{"nullable":true,"type":"number"},"current_lon":{"nullable":true,"type":"number"},"dot_number":{"type":"string"},"is_inbound":{"type":"boolean"}},"required":["dot_number","is_inbound"],"type":"object"},"CarrierRecommendation":{"properties":{"add_date":{"type":"string"},"bipd_insurance_on_file":{"type":"number"},"cargo_insurance_on_file":{"type":"number"},"carried_cargo":{"type":"string"},"carrier_driver_oos_rate":{"type":"number"},"carrier_driver_oos_rate_national_avg":{"type":"number"},"carrier_score_scaled":{"type":"number"},"carrier_total_power_units":{"type":"number"},"carrier_vehicle_oos_rate":{"type":"number"},"carrier_vehicle_oos_rate_national_avg":{"type":"number"},"confirmed_email":{"type":"object","properties":{"<email@domain.com>":{"type":"object","properties":{"add_date":{"type":"string"}}}}},"confirmed_phone":{"type":"object","properties":{"<phone_number>":{"type":"object","properties":{"add_date":{"type":"string"}}}}},"dba_name":{"nullable":true,"type":"string"},"dot_number":{"type":"string"},"email_address":{"type":"string"},"is_inbound":{"type":"boolean"},"is_real_time":{"type":"boolean"},"is_visually_sighted":{"type":"boolean"},"is_possible_backhaul":{"type":"boolean"},"lat":{"nullable":true,"type":"number"},"legal_name":{"type":"string"},"lon":{"nullable":true,"type":"number"},"mc_number":{"type":"number"},"phy_city":{"type":"string"},"phy_state":{"type":"string"},"phy_street":{"type":"string"},"phy_zip":{"type":"string"},"telephone":{"type":"string"},"power_only":{"type":"boolean"},"broker_authority_status":{"type":"string"}},"required":["add_date","bipd_insurance_on_file","cargo_insurance_on_file","carried_cargo","carrier_driver_oos_rate","carrier_driver_oos_rate_national_avg","carrier_score_scaled","carrier_total_power_units","carrier_vehicle_oos_rate","carrier_vehicle_oos_rate_national_avg","confirmed_email","confirmed_phone","dot_number","email_address","is_inbound","is_real_time","is_visually_sighted","legal_name","mc_number","phy_city","phy_state","phy_street","phy_zip","telephone"],"type":"object"}}}}
```

[^1]: Requests can include all location parameters, but only one set is required. You may provide either **origin\_city** and **origin\_state**, or **destination\_city** and **destination\_state**. If neither set is included, the API will return a *400 Bad Request* error:\
    `{"error": "At least one of origin or destination are required."}`


# Real time Capabilities

Real time Capabilities of the Carrier Recommendations Endpoint

With GenLogs' Real-Time API, you can instantly identify carriers with the right equipment who are currently within a 150-mile radius of your origin and are likely seeking backhauls to your destination. Integrate Real-Time GenLogs data into your TMS and internal systems to unlock new opportunities, increase efficiency, and reduce empty miles.

When the real\_time parameter is set to 'True', the recommendation system prioritizes real-time data by applying additional weight to recent detections near the origin of the search. While the recommendations still incorporate historical data and follow the usual logic, the real-time information takes precedence, resulting in a more dynamic focus on current activity.

### Permissions

The `realtime-api` permission is required to use this parameter.

{% hint style="warning" %}
*The* `real_time` *parameter is available exclusively to premium users. Reach out to us at* [*support@genlogs.io*](mailto:support@genlogs.io) *now to unlock Real-Time freight data.*
{% endhint %}

### **Endpoint** <a href="#endpoint" id="endpoint"></a>

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

### **Headers** <a href="#headers" id="headers"></a>

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

### **Query Parameters** <a href="#query-parameters" id="query-parameters"></a>

Use the `real_time` parameter in addition to the required and optional base parameters described in the [Carrier Recommendations](https://docs.genlogs.io/carrier/recommendations#query-parametersreal_time) document.

1. **real\_time** (boolean, optional): Indicates whether to return recommendations that include real-time detections. If enabled, carriers recently seen within 150-mi of your search radius will be returned.

*Tip: A 403 error received while using the real\_time parameter signifies that your user account lacks access to this premium feature. To resolve this, please verify your access level. If you require further assistance, don't hesitate to contact our support team at* [*support@genlogs.io*](mailto:support@genlogs.io)*.*

### **Response Body** <a href="#response-body" id="response-body"></a>

1. **real\_time\_locs** (dictionary of locations where real time carrier observations)
   1. dot\_number: string, usdot of the detected carrier.
   2. current\_lon: float, longitude of the detection location.
   3. current\_lat: float, latitude of the detection location.
   4. is\_inbound (bool): flag indicates when a carrier is currently inbound to the origin
2. **recommendations** (array of `CarrierRecommendation` objects): List of recommended carriers. See [Carrier Recommendation](https://docs.genlogs.io/carrier/recommendations#response-body) docs for more.
3. `is_inbound` appears in: \[1] real\_time\_locs\[is\_inbound], \[2] rt\_detection\_detail\[]\[is\_inbound] – both mean carrier inbound to origin.

Request Example

```
curl -X GET 'https://api.genlogs.io/carrier/recommendations?origin_city=Tucker&origin_state=Georgia&destination_city=Orange+Park&destination_state=Florida&origin_radius=50.0&destination_radius=50.0&fleet_size_min=0&fleet_size_max=1000&preferred_carriers=True&real_time=True' \
-H 'Access-Token: {access_token}' \
-H 'x-api-key: {your_api_key}' \
-i
```

{% openapi src="/files/UYtSuHG8wztE6yerobcS" path="/carrier/recommendations" method="get" %}
[last\_carrier\_api\_12\_feb2025.json](https://2315646207-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTWLd9L6wPqgOLglGkVHP%2Fuploads%2FW4aGbEH2IhULS0FeBW7u%2Flast_carrier_api_12_feb2025.json?alt=media\&token=5745b6f7-f435-451f-8ed3-16816a7d9cf7)
{% endopenapi %}


# Carrier Profile

### Carrier Profile Endpoint

Retrieve **FMCSA** details, **Equipment Pairings**, and **USDOT Sightings** for one or more carriers, with optional date filters for sightings.

### **Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### Permissions

| Permission                     | Effect                           |
| ------------------------------ | -------------------------------- |
| `external-api-carrier-profile` | Required to access this endpoint |

### **Endpoint**

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

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.&#x20;

### **Query Parameters:**

* **usdot\_numbers** (*string, required, max = 50*): One or more USDOT numbers, separated by commas; *e.g. "123456,987654".*
* **start\_date** (*string, optional*): Start date for filtering USDOT sightings (up to 3 years ago); *e.g. "2026-02-20".*
* **end\_date** (*string, optional*): End date for filtering USDOT sightings (cannot exceed the current date); *e.g. "2026-02-21".*

### Understanding carrier profile information

{% hint style="info" %}
Responses are always grouped by **USDOT**, and within each USDOT you may find:

* **FMCSA Detail** – always present.
* **Equipment Pairings** – may be empty depending on the available information.
* **USDOT Sightings** – may be empty depending on the filters applied.

This means that while **FMCSA Detail** is guaranteed for every USDOT, the **Pairing Data** and **Sightings** sections may not return results if they do not match the requested filters.
{% endhint %}

**Carrier Profile returns three arrays per USDOT.**

* **FMCSA Detail**: FMCSA details with equipment pairings and USDOT sightings for specified carriers
  * **usdot\_number**: (string) The USDOT number for the carrier.
  * **docket\_numbe**r: (string) The Motor Carrier number for carriers involved in interstate.
  * **legal\_name**: (string) The official registered name of the carrier.
  * **dba\_name**: (string)  The "Doing Business As" name, if applicable.
  * **carrier\_status**: (string) Indicates whether the carrier is active, inactive, or has a pending status.
  * **entity\_status**: (string) Refers to the legal standing of the carrier's business entity.
  * **carrier\_ein**: (string) It is a unique nine-digit number assigned by the IRS to identify the carrier for tax purposes.
  * **dun\_bradstreet\_no**: (string) It is a unique identifier assigned by Dun & Bradstreet to businesses.
  * **mcs150\_date**: (strin&#x67;**)** The date when the carrier last updated their MCS-150 form (Motor Carrier Identification Report).
  * **mcs150\_mileage**: (strin&#x67;**)** The total mileage reported by the carrier on their MCS-150 form, typically for the previous year.
  * **insurer\_company\_name**: (string)  The name of the insurance company providing coverage for the carrier.
  * **insurance\_docket\_number**: (string) A unique identifier for the insurance filing associated with the carrier.
  * **insurance\_policy\_number**: (strin&#x67;**)** The policy number assigned by the insurer to the carrier's insurance policy.
  * **insurance\_policy\_type**: (string) Specifies the type of insurance policy (e.g., liability, cargo, etc.).
  * **insurance\_form\_code**: (string) A code representing the type of insurance form filed (e.g., BMC-91 for liability insurance).
  * **insurance\_max\_coverage\_amount**: (string) The maximum coverage amount provided by the insurance policy.
  * **insurance\_underlying\_limit\_amount**: (string) The underlying limit amount, which is the base coverage before additional layers of insurance apply.
  * **insurance\_transaction\_date**: (string) The date when the insurance transaction (e.g., filing or update) was processed.
  * **insurance\_effective\_date**: (string) The start date of the insurance policy.
  * **insurance\_expiration\_date**: (string) The end date of the insurance policy.
  * **phy\_street:** (string) The street address of the carrier's physical location.
  * **phy\_city**: (string) The city where the carrier's physical address is located.
  * **phy\_state**: (string) The state where the carrier's physical address is located.
  * **phy\_zip**: (string) The ZIP code for the carrier's physical address.
  * **telephone**: (string) The carrier's primary contact phone number.
  * **email\_address**: (string) The carrier's email address for communication.
  * **mailing\_street**: (string) The street address of the carrier's mailing location.
  * **mailing\_city**: (string) The city where the carrier's mailing address is located.
  * **mailing\_state**: (string) The state where the carrier's mailing address is located.
  * **mailing\_zip**: (string) The ZIP code for the carrier's mailing address.
  * **mailing\_country**: (string) The country of the carrier's mailing address.
  * **carrier\_operation**: (string) Describes the type of operations the carrier is authorized to perform (e.g., interstate, intrastate, hazardous materials).
  * **operation\_classificiation**: (string) Specifies the classification of the carrier's operations, such as for-hire, private, exempt, or passenger.
  * **authority\_date**: (string) The date when the carrier's operating authority was granted.
  * **authorized\_for\_common\_date**: (string) The date when the carrier was authorized for common carrier operations.
  * **authorized\_for\_contract\_date**: (string) The date when the carrier was authorized for contract carrier operations.
  * **carrier\_total\_drivers**: (string) The total number of drivers employed by the carrier.
  * **carrier\_total\_power\_units**: (string) The total number of power units (e.g., trucks, tractors) operated by the carrier.
  * **carried\_cargo**: (string) The types of cargo the carrier is authorized to transport (e.g., general freight, hazardous materials).
  * **carrier\_driver\_insp**: (string) The total number of driver inspections conducted for the carrier.
  * **carrier\_driver\_oos\_insp**: (string) The number of driver inspections that resulted in an out-of-service (OOS) order.
  * **carrier\_driver\_oos\_rate**: (number) The percentage of driver inspections that resulted in an OOS order.
  * **carrier\_driver\_oos\_rate\_national\_avg**: (number) The national average OOS rate for drivers, used for comparison.
  * **carrier\_vehicle\_insp**: (string) The total number of vehicle inspections conducted for the carrier.
  * **carrier\_vehicle\_oos\_insp**: (string) The number of vehicle inspections that resulted in an OOS order.
  * **carrier\_vehicle\_oos\_rate**: (number) The percentage of vehicle inspections that resulted in an OOS order.
  * **carrier\_vehicle\_oos\_rate\_national\_avg**: (number) The national average OOS rate for vehicles, used for comparison.
  * **carrier\_hazmat\_insp**: (string) The total number of hazardous materials inspections conducted for the carrier.
  * **carrier\_hazmat\_oos\_insp**: (string) The number of hazardous materials inspections that resulted in an OOS order.
  * **carrier\_hazmat\_oos\_rate**: (number) The percentage of hazardous materials inspections that resulted in an OOS order.
  * **carrier\_hazmat\_oos\_rate\_national\_avg**: (number) The national average OOS rate for hazardous materials, used for comparison.
  * **carrier\_fatal\_crash**: (string) The total number of fatal crashes involving the carrier.
  * **carrier\_inj\_crash**: (string) The total number of crashes involving injuries for the carrier.
  * **carrier\_towaway\_crash**: (string)  The total number of crashes involving towaways for the carrier.&#x20;
  * **carrier\_crash\_total**: (string) The total number of crashes involving the carrier, including all types of crashes (fatal, injury, and towaway).
  * **recordable\_crash\_rate**: (number) The rate of recordable crashes per million vehicle miles traveled (VMT). This metric helps assess the carrier's safety performance.
  * **basic\_unsafe\_driving\_total\_violation**: (string) The total number of violations related to unsafe driving (e.g., speeding, reckless driving) recorded for the carrier.
  * **basic\_driver\_fitness\_total\_violation**: (string) The total number of violations related to driver fitness (e.g., invalid licenses, medical qualifications).
  * **basic\_hos\_total\_violation**: (string) The total number of violations related to Hours of Service (HOS) compliance (e.g., exceeding driving time limits, falsifying logs).
  * **basic\_drugs\_alcohol\_total\_violation**: (string) The total number of violations related to drug and alcohol use by drivers.
  * **basic\_vehicle\_maint\_total\_violation**: (string) The total number of violations related to vehicle maintenance (e.g., brake issues, lighting problems).
  * **carrier\_safety\_rating\_date**: (string) The date when the carrier's most recent safety rating was issued.
  * **carrier\_safety\_rating**: (string)&#x20;

    The carrier's safety rating, which can be one of the following:

    * **Satisfactory**: Meets safety standards.
    * **Conditional**: Does not meet all safety standards but is allowed to operate.
    * **Unsatisfactory**: Fails to meet safety standards and is not allowed to operate.
  * **carrier\_safety\_review\_date**: (string)  The date when the carrier's most recent safety review was conducted.
  * **carrier\_safety\_review\_type**: (string) The type of safety review conducted (e.g., compliance review, safety audit).
* **Equipment Pairings**: equipment pairings for specified carriers, as observed by GenLogs:
  * name: equipment type name
  * value\_percent: percentage score
* **USDOT Sightings**: Retrieves USDOT sightings for specified carriers within a date range.
  * sighting\_date: Date when the sighting occurred.
  * state\_seen: U.S. state where the sighting was recorded.
  * location\_zip: 3-digit ZIP code prefix representing the location of the sighting.
  * sightings: amount of registered GenLogs sightings.
  * source: the source of the sighting (e.g. "detections")

### **Response:**

* **200 OK:** A JSON object containing 3 sets of carrier details.
* **400 Bad Request:** If required parameters are missing or invalid.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been added to your user.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

* Data (object of `CarrierProfile` objects): Set of carrier profiles grouped by `usdot_number`.

### Request Example:

```
curl --location 'https://api.genlogs.io/carrier/profile?usdot_number=2350084%2C10553&start_date=2025-09-01&end_date=2025-09-12' \
--header 'Access-Token: {your-user-token}' \
--header 'x-api-key: {your-x-api-key}'
```

## Get carrier profile details

> Retrieve a comprehensive carrier profile including FMCSA details, equipment pairings, and sightings data for specified USDOT numbers.\
> Roles must include \`external-api-carrier-profile\`. FMCSA hazmat inspection/OOS statistics remain available on \`fmcsa\_detail.carrier\_hazmat\_\*\` for all callers.<br>

```json
{"openapi":"3.0.3","info":{"title":"Carrier Profile API","version":"1.0.0"},"tags":[{"name":"Carrier Profile","description":"Carrier profile endpoint"}],"servers":[{"url":"https://api.genlogs.io","description":"Production"}],"paths":{"/carrier/profile":{"get":{"tags":["Carrier Profile"],"summary":"Get carrier profile details","description":"Retrieve a comprehensive carrier profile including FMCSA details, equipment pairings, and sightings data for specified USDOT numbers.\nRoles must include `external-api-carrier-profile`. FMCSA hazmat inspection/OOS statistics remain available on `fmcsa_detail.carrier_hazmat_*` for all callers.\n","operationId":"getCarrierProfileDetail","parameters":[{"in":"header","name":"Access-Token","required":true,"schema":{"type":"string"},"description":"Token for authentication"},{"in":"query","name":"usdot_number","required":true,"schema":{"type":"array","items":{"type":"string"}},"style":"form","explode":false,"description":"USDOT numbers to filter data for specific carriers"},{"in":"query","name":"start_date","required":false,"schema":{"type":"string","format":"date"},"description":"Inclusive start date (YYYY-MM-DD) for sightings. Omit for full history."},{"in":"query","name":"end_date","required":false,"schema":{"type":"string","format":"date"},"description":"Inclusive end date (YYYY-MM-DD) for sightings. Omit for full history."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/CarrierProfile"}}}}},"400":{"description":"Bad Request - invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized – missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden – invalid token or insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"CarrierProfile":{"type":"object","description":"Per-USDOT carrier profile payload.","properties":{"fmcsa_detail":{"$ref":"#/components/schemas/FmcsaDetail"},"equipment_pairings":{"$ref":"#/components/schemas/EquipmentPairings"},"sightings":{"type":"array","items":{"$ref":"#/components/schemas/Sighting"}}},"required":["fmcsa_detail","equipment_pairings","sightings"]},"FmcsaDetail":{"type":"object","properties":{"usdot_number":{"type":"string"},"legal_name":{"type":"string"},"dba_name":{"type":"string"},"entity_type":{"type":"string"},"carrier_operation":{"type":"string"},"cargo_carried":{"type":"string"},"hazmat_authorized":{"type":"string"},"carrier_status":{"type":"string"},"out_of_service_date":{"type":"string"},"legal_address":{"type":"string"},"physical_address":{"type":"string"},"mailing_address":{"type":"string"},"telephone":{"type":"string"},"fax":{"type":"string"},"email":{"type":"string"},"mcs_150_form_date":{"type":"string","format":"date"},"mcs_150_mileage_year":{"type":"string"},"dot_number":{"type":"string"},"docket_number":{"type":"string"},"mc_mx_ff_number":{"type":"string"},"power_units":{"type":"string"},"drivers":{"type":"string"},"mcs_150_mileage":{"type":"string"},"carrier_hazmat_insp":{"type":"number","description":"FMCSA hazmat inspection count."},"carrier_hazmat_oos_insp":{"type":"number","description":"FMCSA hazmat out-of-service inspection count."},"carrier_hazmat_oos_rate":{"type":"number","format":"float","description":"FMCSA hazmat out-of-service rate."},"carrier_hazmat_oos_rate_national_avg":{"type":"number","format":"float","description":"FMCSA national average hazmat out-of-service rate."}}},"EquipmentPairings":{"type":"object","properties":{"genlogs":{"type":"array","items":{}},"fmcsa":{"type":"array","items":{}}}},"Sighting":{"type":"object","description":"A single sighting record for a carrier location/date.","properties":{"sighting_date":{"type":"string","format":"date"},"state_seen":{"type":"string"},"location_zip":{"type":"string"},"sightings":{"type":"integer","description":"Count of sightings for this location/date."},"source":{"type":"string","description":"Data source of the sighting (e.g. visual, api)."}}},"ErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"integer","format":"int32"}},"required":["message","code"]}}}}
```


# Carrier FMCSA Insurance

## Carrier FMCSA Insurance Endpoint

Retrieve standalone **FMCSA insurance** data (active insurance and insurance history) for one or more carriers, without pulling FMCSA detail, sightings, equipment, or scores.

{% hint style="info" %}
Need everything at once (FMCSA detail, equipment pairings, sightings, and all FI-aligned sections)? Use `GET /carrier/profile` instead ( [Carrier Profile](/carrier/carrier-profile#carrier-profile-endpoint) ) — it returns everything in one call, including this `insurance` section.
{% endhint %}

### **Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### Permissions

| Permission                             | Effect                           |
| -------------------------------------- | -------------------------------- |
| `external-api-carrier-fmcsa-insurance` | Required to access this endpoint |

### **Endpoint**

* **URL:** `https://api.genlogs.io/carrier/profile/fmcsa/insurance`
* **Method:** `GET`

### **Headers**

* **Access-Token**: (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.

### **Query Parameters:**

* **usdot\_number** (*array of string, required*): One or more USDOT numbers; repeat the parameter for multiple values, *e.g. `?usdot_number=10553&usdot_number=2350084`.*

#### Understanding FMCSA insurance information

{% hint style="info" %}
Responses are grouped by **USDOT**. Each USDOT that exists in FMCSA data returns an `insurance` object with a `policies` array; USDOTs that don't exist are omitted from the response entirely (not returned as an empty object).
{% endhint %}

**FMCSA Insurance returns one object per USDOT:**

* **insurance**: Active insurance and insurance history for the carrier.
  * **policies** (array): One entry per insurance policy on file.
    * **insurer\_name**: (string, nullable) The name of the insurance company providing coverage for the carrier.
    * **policy\_type**: (string, nullable) The type of insurance policy (e.g., BIPD, Cargo).
    * **max\_coverage\_amount**: (number, nullable) The maximum coverage amount in US dollars (USD).
    * **underlying\_limit\_amount**: (number, nullable) The underlying / minimum coverage limit in US dollars (USD).
    * **effective\_date**: (string, nullable) The start date of the insurance policy (YYYY-MM-DD).
    * **expiration\_date**: (string, nullable) The end date of the insurance policy (YYYY-MM-DD).

#### **Response:**

* **200 OK:** A JSON object containing an `insurance` section per requested USDOT.
* **400 Bad Request:** If `usdot_number` is missing, empty, or exceeds the allowed limit.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the `external-api-carrier-fmcsa-insurance` permission has not been added to your user.
* **404 Not Found**: If none of the requested USDOT numbers exist.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

#### **Response Body:**

* Data (object): Set of `{ "insurance": { "policies": [...] } }` objects grouped by `usdot_number`.

#### Request Example:

```
curl --location 'https://api.genlogs.io/carrier/profile/fmcsa/insurance?usdot_number=10553' \
--header 'Access-Token: {your-user-token}' \
--header 'x-api-key: {your-x-api-key}'
```

#### Response Example:

```json
{
  "10553": {
    "insurance": {
      "policies": [
        {
          "insurer_name": "Example Insurance Co",
          "policy_type": "BIPD",
          "max_coverage_amount": 1000000,
          "underlying_limit_amount": 750000,
          "effective_date": "2024-01-01",
          "expiration_date": "2025-01-01"
        }
      ]
    }
  }
}
```

## Get carrier FMCSA insurance

> Retrieve standalone FMCSA insurance data (active insurance and insurance history) for specified USDOT numbers, without pulling FMCSA detail, sightings, equipment, or scores.\
> Roles must include \`external-api-carrier-fmcsa-insurance\`.<br>

```json
{"openapi":"3.0.3","info":{"title":"Carrier Profile API","version":"1.0.0"},"tags":[{"name":"Carrier Profile","description":"Carrier profile endpoint"}],"servers":[{"url":"https://api.genlogs.io","description":"Production"}],"paths":{"/carrier/profile/fmcsa/insurance":{"get":{"tags":["Carrier Profile"],"summary":"Get carrier FMCSA insurance","description":"Retrieve standalone FMCSA insurance data (active insurance and insurance history) for specified USDOT numbers, without pulling FMCSA detail, sightings, equipment, or scores.\nRoles must include `external-api-carrier-fmcsa-insurance`.\n","operationId":"getCarrierFmcsaInsurance","parameters":[{"in":"header","name":"Access-Token","required":true,"schema":{"type":"string"},"description":"Token for authentication"},{"in":"header","name":"x-api-key","required":true,"schema":{"type":"string"},"description":"GenLogs generated API Key for authentication"},{"in":"query","name":"usdot_number","required":true,"schema":{"type":"array","items":{"type":"string"}},"style":"form","explode":false,"description":"USDOT numbers to get FMCSA insurance for"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/FmcsaInsuranceItem"}}}}},"400":{"description":"Bad Request - invalid or missing usdot_number","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized – missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden – invalid token or insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - none of the requested USDOT numbers exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"FmcsaInsuranceItem":{"type":"object","description":"Per-USDOT payload for `GET /carrier/profile/fmcsa/insurance`.","properties":{"insurance":{"$ref":"#/components/schemas/Insurance"}},"required":["insurance"]},"Insurance":{"type":"object","properties":{"policies":{"type":"array","items":{"$ref":"#/components/schemas/InsurancePolicy"}}}},"InsurancePolicy":{"type":"object","properties":{"insurer_name":{"type":"string","nullable":true},"policy_type":{"type":"string","nullable":true},"max_coverage_amount":{"type":"number","format":"float","nullable":true,"description":"Maximum coverage amount in US dollars (USD)."},"underlying_limit_amount":{"type":"number","format":"float","nullable":true,"description":"Underlying / minimum coverage limit in US dollars (USD)."},"effective_date":{"type":"string","format":"date","nullable":true},"expiration_date":{"type":"string","format":"date","nullable":true}}},"ErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"integer","format":"int32"}},"required":["message","code"]}}}}
```


# Carrier FMCSA Scores

### Carrier FMCSA Scores Endpoint

Retrieve standalone **ISS score** and **BASIC scores** (with history and violation summaries) for one or more carriers, without pulling FMCSA detail, sightings, equipment, or insurance.

{% hint style="info" %}
Need everything at once (FMCSA detail, equipment pairings, sightings, and all FI-aligned sections)? Use `GET /carrier/profile` instead ( [Carrier Profile](/carrier/carrier-profile#carrier-profile-endpoint) ) — it returns everything in one call, including `iss_score` and `basic_scores`. &#x20;
{% endhint %}

### **Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### Permissions

| Permission                          | Effect                                                             |
| ----------------------------------- | ------------------------------------------------------------------ |
| `external-api-carrier-fmcsa-scores` | Required to access this endpoint                                   |
| `external-api-carrier-iss-score`    | Required for the `iss_score` section; omitted (not null) otherwise |

### **Endpoint**

* **URL:** `https://api.genlogs.io/carrier/profile/fmcsa/scores`
* **Method:** `GET`

### **Headers**

* **Access-Token**: (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.

### **Query Parameters:**

* **usdot\_number** (*array of string, required*): One or more USDOT numbers; repeat the parameter for multiple values, *e.g. `?usdot_number=10553&usdot_number=2350084`.*
* **start\_date** (*string, optional*): Inclusive start date (YYYY-MM-DD) for `score_over_time` windows on both `iss_score` and `basic_scores`. Omit for full history.
* **end\_date** (*string, optional*): Inclusive end date (YYYY-MM-DD) for `score_over_time` windows. Omit for full history.

### Understanding FMCSA scores information

{% hint style="info" %}
Responses are grouped by **USDOT**. USDOTs that don't exist in FMCSA data are omitted from the response entirely. Callers without `external-api-carrier-iss-score` will not see the `iss_score` key at all (it's omitted, not returned as null).
{% endhint %}

**FMCSA Scores returns one object per USDOT:**

* **iss\_score** (object, nullable — only present with `external-api-carrier-iss-score`):
  * **score**: (integer, nullable) Current ISS score.
  * **score\_over\_time**: (array) `{ date, score }` points, sorted ascending by date.
* **basic\_scores** (object): One entry per BASIC category — `unsafe_driving`, `driver_fitness`, `hos`, `drugs_alcohol`, `vehicle_maintenance`. Each category (nullable if no data) has:
  * **score**: (integer, nullable) Current BASIC percentile score.
  * **score\_over\_time**: (array) `{ date, score }` points, sorted ascending by date.
  * **violation\_summary**: (array) `{ weight, category, total, out_of_service }` — aggregated violation counts for that BASIC category.

### **Response:**

* **200 OK:** A JSON object containing `iss_score` (if permitted) and `basic_scores` per requested USDOT.
* **400 Bad Request:** If `usdot_number` is missing/empty, exceeds the allowed limit, or `start_date`/`end_date` is not valid YYYY-MM-DD.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the `external-api-carrier-fmcsa-scores` permission has not been added to your user.
* **404 Not Found**: If none of the requested USDOT numbers exist.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

* Data (object): Set of `{ "iss_score": {...}, "basic_scores": {...} }` objects grouped by `usdot_number`.

### Request Example:

```
curl --location 'https://api.genlogs.io/carrier/profile/fmcsa/scores?usdot_number=10553&start_date=2025-01-01&end_date=2025-09-01' \
--header 'Access-Token: {your-user-token}' \
--header 'x-api-key: {your-x-api-key}'
```

### Response Example:

```json
{
  "10553": {
    "iss_score": {
      "score": 68,
      "score_over_time": [
        { "date": "2025-01-01", "score": 65 },
        { "date": "2025-02-01", "score": 68 }
      ]
    },
    "basic_scores": {
      "unsafe_driving": {
        "score": 72,
        "score_over_time": [{ "date": "2025-02-01", "score": 70 }],
        "violation_summary": [
          { "weight": 5, "category": "Speeding", "total": 8, "out_of_service": 0 }
        ]
      },
      "driver_fitness": null,
      "hos": null,
      "drugs_alcohol": null,
      "vehicle_maintenance": null
    }
  }
}
```

## Get carrier FMCSA scores

> Retrieve standalone ISS score and BASIC scores (with history and violation summaries) for specified USDOT numbers, without pulling FMCSA detail, sightings, equipment, or insurance.\
> Roles must include \`external-api-carrier-fmcsa-scores\`. The \`iss\_score\` key is additionally gated on \`external-api-carrier-iss-score\`; without it, \`iss\_score\` is omitted entirely (not null).<br>

```json
{"openapi":"3.0.3","info":{"title":"Carrier Profile API","version":"1.0.0"},"tags":[{"name":"Carrier Profile","description":"Carrier profile endpoint"}],"servers":[{"url":"https://api.genlogs.io","description":"Production"}],"paths":{"/carrier/profile/fmcsa/scores":{"get":{"tags":["Carrier Profile"],"summary":"Get carrier FMCSA scores","description":"Retrieve standalone ISS score and BASIC scores (with history and violation summaries) for specified USDOT numbers, without pulling FMCSA detail, sightings, equipment, or insurance.\nRoles must include `external-api-carrier-fmcsa-scores`. The `iss_score` key is additionally gated on `external-api-carrier-iss-score`; without it, `iss_score` is omitted entirely (not null).\n","operationId":"getCarrierFmcsaScores","parameters":[{"in":"header","name":"Access-Token","required":true,"schema":{"type":"string"},"description":"Token for authentication"},{"in":"header","name":"x-api-key","required":true,"schema":{"type":"string"},"description":"GenLogs generated API Key for authentication"},{"in":"query","name":"usdot_number","required":true,"schema":{"type":"array","items":{"type":"string"}},"style":"form","explode":false,"description":"USDOT numbers to get FMCSA scores for"},{"in":"query","name":"start_date","required":false,"schema":{"type":"string","format":"date"},"description":"Inclusive start date (YYYY-MM-DD) for score_over_time windows. Omit for full history."},{"in":"query","name":"end_date","required":false,"schema":{"type":"string","format":"date"},"description":"Inclusive end date (YYYY-MM-DD) for score_over_time windows. Omit for full history."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/FmcsaScoresItem"}}}}},"400":{"description":"Bad Request - invalid or missing usdot_number, or invalid start_date/end_date","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized – missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden – invalid token or insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - none of the requested USDOT numbers exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"FmcsaScoresItem":{"type":"object","description":"Per-USDOT payload for `GET /carrier/profile/fmcsa/scores`.","properties":{"iss_score":{"nullable":true,"description":"Omitted entirely when the caller lacks the external-api-carrier-iss-score permission.","allOf":[{"$ref":"#/components/schemas/IssScore"}]},"basic_scores":{"$ref":"#/components/schemas/BasicScores"}},"required":["basic_scores"]},"IssScore":{"type":"object","properties":{"score":{"type":"integer","nullable":true},"score_over_time":{"type":"array","items":{"$ref":"#/components/schemas/ScoreOverTimePoint"}}}},"ScoreOverTimePoint":{"type":"object","description":"A single score observation. Arrays of these points are sorted ascending by date (oldest first).","properties":{"date":{"type":"string","format":"date","description":"Observation date (YYYY-MM-DD)."},"score":{"type":"integer","nullable":true,"description":"Score for that date. Null when a history row has a valid date but the underlying score (or BASIC percentile) is missing or unparseable."}},"required":["date"]},"BasicScores":{"type":"object","properties":{"unsafe_driving":{"$ref":"#/components/schemas/BasicScoreCategory"},"driver_fitness":{"$ref":"#/components/schemas/BasicScoreCategory"},"hos":{"$ref":"#/components/schemas/BasicScoreCategory"},"drugs_alcohol":{"$ref":"#/components/schemas/BasicScoreCategory"},"vehicle_maintenance":{"$ref":"#/components/schemas/BasicScoreCategory"}},"required":["unsafe_driving","driver_fitness","hos","drugs_alcohol","vehicle_maintenance"]},"BasicScoreCategory":{"type":"object","nullable":true,"properties":{"score":{"type":"integer","nullable":true},"score_over_time":{"type":"array","items":{"$ref":"#/components/schemas/ScoreOverTimePoint"}},"violation_summary":{"type":"array","items":{"$ref":"#/components/schemas/ViolationSummaryRow"}}}},"ViolationSummaryRow":{"type":"object","properties":{"weight":{"type":"integer","nullable":true,"description":"FMCSA severity weight for the violation category."},"category":{"type":"string","nullable":true,"description":"Violation category label."},"total":{"type":"integer","nullable":true,"description":"Total violations in this category."},"out_of_service":{"type":"integer","nullable":true,"description":"Count of out-of-service violations in this category."}}},"ErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"integer","format":"int32"}},"required":["message","code"]}}}}
```


# Carrier FMCSA Violations

### Carrier FMCSA Violations Endpoint

Retrieve standalone **FMCSA violation history** (per-inspection violation rows) for one or more carriers, without pulling FMCSA detail, sightings, equipment, scores, or insurance.

{% hint style="info" %}
Need everything at once (FMCSA detail, equipment pairings, sightings, and all FI-aligned sections)? Use `GET /carrier/profile` instead ( [Carrier Profile](/carrier/carrier-profile#carrier-profile-endpoint) ) — it returns everything in one call. `basic_scores.*.violation_summary` there gives aggregated counts; this endpoint gives per-inspection detail.
{% endhint %}

### **Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### Permissions

| Permission                              | Effect                           |
| --------------------------------------- | -------------------------------- |
| `external-api-carrier-fmcsa-violations` | Required to access this endpoint |

### **Endpoint**

* **URL:** `https://api.genlogs.io/carrier/profile/fmcsa/violations`
* **Method:** `GET`

### **Headers**

* **Access-Token**: (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.

### **Query Parameters:**

* **usdot\_number** (*array of string, required*): One or more USDOT numbers; repeat the parameter for multiple values, *e.g. `?usdot_number=10553&usdot_number=2350084`.*
* **start\_date** (*string, optional*): Inclusive start date (YYYY-MM-DD) for `inspection_date` filtering. Omit for full history.
* **end\_date** (*string, optional*): Inclusive end date (YYYY-MM-DD) for `inspection_date` filtering. Omit for full history.

### Understanding FMCSA violations information

{% hint style="info" %}
Responses are grouped by **USDOT**. Each USDOT that exists in FMCSA data returns a `violations` array (empty if no violations in range); USDOTs that don't exist are omitted from the response entirely. Violations are sorted by `inspection_date` descending (most recent first).
{% endhint %}

**FMCSA Violations returns one object per USDOT:**

* **violations** (array): One entry per inspection violation record.
  * **report\_number**: (string, nullable) The inspection report number.
  * **inspection\_date**: (string, nullable) Date of the inspection (YYYY-MM-DD).
  * **violation\_code**: (string, nullable) FMCSA violation code.
  * **description**: (string, nullable) Human-readable violation description.
  * **vins**: (array of string, nullable) VIN(s) associated with the violation.
  * **basic\_category**: (string, nullable) BASIC category the violation rolls up to (e.g. Unsafe Driving).
  * **basic\_severity\_weight**: (integer, nullable) FMCSA severity weight for the violation.
  * **oos**: (boolean, nullable) Whether the violation resulted in an out-of-service order.
  * **oos\_weight**: (integer, nullable) Out-of-service weight, if applicable.

### **Response:**

* **200 OK:** A JSON object containing a `violations` array per requested USDOT.
* **400 Bad Request:** If `usdot_number` is missing/empty, exceeds the allowed limit, or `start_date`/`end_date` is not valid YYYY-MM-DD.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the `external-api-carrier-fmcsa-violations` permission has not been added to your user.
* **404 Not Found**: If none of the requested USDOT numbers exist.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

* Data (object): Set of `{ "violations": [...] }` objects grouped by `usdot_number`.

### Request Example:

```
curl --location 'https://api.genlogs.io/carrier/profile/fmcsa/violations?usdot_number=10553&start_date=2025-01-01&end_date=2025-09-01' \
--header 'Access-Token: {your-user-token}' \
--header 'x-api-key: {your-x-api-key}'
```

### Response Example:

```json
{
  "10553": {
    "violations": [
      {
        "report_number": "CA123456",
        "inspection_date": "2025-03-14",
        "violation_code": "392.2S",
        "description": "Speeding 6-10 mph over limit",
        "vins": ["1FUJA6CK67LX14816"],
        "basic_category": "Unsafe Driving",
        "basic_severity_weight": 5,
        "oos": false,
        "oos_weight": null
      }
    ]
  }
}
```

## Get carrier FMCSA violations

> Retrieve standalone FMCSA violation history (per-inspection violation rows) for specified USDOT numbers, without pulling FMCSA detail, sightings, equipment, scores, or insurance. Violations are sorted by inspection\_date descending (most recent first).\
> Roles must include \`external-api-carrier-fmcsa-violations\`.<br>

```json
{"openapi":"3.0.3","info":{"title":"Carrier Profile API","version":"1.0.0"},"tags":[{"name":"Carrier Profile","description":"Carrier profile endpoint"}],"servers":[{"url":"https://api.genlogs.io","description":"Production"}],"paths":{"/carrier/profile/fmcsa/violations":{"get":{"tags":["Carrier Profile"],"summary":"Get carrier FMCSA violations","description":"Retrieve standalone FMCSA violation history (per-inspection violation rows) for specified USDOT numbers, without pulling FMCSA detail, sightings, equipment, scores, or insurance. Violations are sorted by inspection_date descending (most recent first).\nRoles must include `external-api-carrier-fmcsa-violations`.\n","operationId":"getCarrierFmcsaViolations","parameters":[{"in":"header","name":"Access-Token","required":true,"schema":{"type":"string"},"description":"Token for authentication"},{"in":"header","name":"x-api-key","required":true,"schema":{"type":"string"},"description":"GenLogs generated API Key for authentication"},{"in":"query","name":"usdot_number","required":true,"schema":{"type":"array","items":{"type":"string"}},"style":"form","explode":false,"description":"USDOT numbers to get FMCSA violations for"},{"in":"query","name":"start_date","required":false,"schema":{"type":"string","format":"date"},"description":"Inclusive start date (YYYY-MM-DD) for inspection_date filtering. Omit for full history."},{"in":"query","name":"end_date","required":false,"schema":{"type":"string","format":"date"},"description":"Inclusive end date (YYYY-MM-DD) for inspection_date filtering. Omit for full history."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/FmcsaViolationsItem"}}}}},"400":{"description":"Bad Request - invalid or missing usdot_number, or invalid start_date/end_date","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized – missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden – invalid token or insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - none of the requested USDOT numbers exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"FmcsaViolationsItem":{"type":"object","description":"Per-USDOT payload for `GET /carrier/profile/fmcsa/violations`.","properties":{"violations":{"type":"array","description":"Sorted by inspection_date descending (most recent first).","items":{"$ref":"#/components/schemas/ViolationRecord"}}},"required":["violations"]},"ViolationRecord":{"type":"object","description":"A single per-inspection FMCSA violation row.","properties":{"report_number":{"type":"string","nullable":true,"description":"The inspection report number."},"inspection_date":{"type":"string","format":"date","nullable":true},"violation_code":{"type":"string","nullable":true,"description":"FMCSA violation code."},"description":{"type":"string","nullable":true,"description":"Human-readable violation description."},"vins":{"type":"array","nullable":true,"items":{"type":"string"},"description":"VIN(s) associated with the violation."},"basic_category":{"type":"string","nullable":true,"description":"BASIC category the violation rolls up to."},"basic_severity_weight":{"type":"integer","nullable":true,"description":"FMCSA severity weight for the violation."},"oos":{"type":"boolean","nullable":true,"description":"Whether the violation resulted in an out-of-service order."},"oos_weight":{"type":"integer","nullable":true,"description":"Out-of-service weight, if applicable."}}},"ErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"integer","format":"int32"}},"required":["message","code"]}}}}
```


# Carrier Contacts

### Carrier Contacts Endpoint&#x20;

Retrieve a list of **Onboarded, Dispatch,** and **FMCSA** contacts for one or more given carriers.&#x20;

### **Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.
* Include **Content-Type: application/json** in the header of the request

### Permissions

The `external-api-carrier-contacts` permission is required to access this endpoint.

### **Endpoint**

* **URL:** `https://api.genlogs.io/carrier/contacts`
* **Method:** `POST`

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.&#x20;

### Request Bod&#x79;**:**

* **usdot\_numbers** (string, required): usdot\_number(s) separated by commas.

### Understanding contact information

{% hint style="info" %}
There are no limitations to the number of contacts retrieved in any category (Onboarded, Dispatch, FMCSA). Each array may have zero contacts, one contact, or multiple contacts.
{% endhint %}

**Carrier Contacts returns three sets of contact information: Dispatch, FMCSA and Onboarded Contacts.**

* **Onboarded Contacts**: values provided from your Onboarded Carrier list, (managed by admins in the UI). If no values are uploaded, they will be blank.
  * `name`
  * `phone`
  * `email`
* **Dispatch contacts**: contacts validated by GenLogs, our customers, or a third party partner. Not available for all carriers:
  * `phone`
  * `email`
* **FMCSA contacts**: contacts provided by the FMCSA. These are shown exactly as registered, including possible null values, multiple semicolon separated values, or values with typos.
  * `name`
  * `phone`
  * `email`

### **Response:**

* **200 OK:** A JSON object containing 3 sets of carrier contacts.
* **400 Bad Request:** If required parameters are missing or invalid.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been added to your user.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

* Data (array of `CarrierContacts` objects): List of carriers contacts grouped by `usdot_number`.
  * `has_dispatch` (string): `Yes` if GenLogs team has confirmed the contact information, otherwise `No`
  * `onboarded_contact`:
    * `name`
    * `phone`
    * `email`
  * dispatch contact:
    * `phone`
    * `email`
  * fmcsa\_contact:
    * `name`
    * `phone`
    * `email`

### Request Example:

```
curl --location 'https://api.genlogs.io/carrier/contacts' \
--header 'access-token: <access-token>' \
--header 'x-api-key: <x-api-key>' \
--header 'Content-Type: application/json' \
--data '{
    "usdot_numbers": "10553"
}'
```

## Get contacts for carriers

> Returns the contacts related to a carrier (onboarded, dispatch and FMCSA).

```json
{"openapi":"3.0.3","info":{"title":"Genlogs Carrier API","version":"1.0.0"},"paths":{"/carrier/contacts":{"post":{"summary":"Get contacts for carriers","description":"Returns the contacts related to a carrier (onboarded, dispatch and FMCSA).","responses":{"200":{"description":"Contacts found","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","additionalProperties":{"type":"object","properties":{"has_dispatch":{"type":"string"},"onboarded_contacts":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"}}}},"dispatch_contact":{"type":"array","items":{"type":"object","properties":{"phone":{"type":"string"},"email":{"type":"string"}}}},"fmcsa_contact":{"type":"object","properties":{"name":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"}}}}}}}}}}},"401":{"description":"Unauthorized – missing token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden – invalid token or insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"ErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"integer","format":"int32"}},"required":["message","code"]}}}}
```


# Onboarded Carriers

This section describes the endpoints available to create and maintain Onboarded Carrier contacts via API.


# Create Onboarded Carriers

Create an onboarded carrier contact associated with a specific USDOT. This endpoint allows customers to add their own validated contact information.

### **Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### Permissions

The `external-api-create-onboarded-carrier-contact` permission is required to access this endpoint.

### **Endpoint**

* **URL:**  `https://api.genlogs.io/onboarded-carrier/contacts`
* **Method:** POST

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.&#x20;

### **Request Body:**

* **usdot** (string, required): Carrier USDOT number. Must contain digits only, be greater than zero, and be at most 9 digits.
* **name** (string, optional): Contact name.&#x20;
* **phone** (string, optional): Contact phone number
* **email** (string, optional): Contact email address.

### Request Example:

```bash
curl --location 'https://api.genlogs.io/onboarded-carrier/contacts' \
--header 'access-token: <your-access-token>' \
--header 'x-api-key: <your-x-api-key>' \
--header 'Content-Type: application/json' \
--data '{
    "usdot": "123456789",
    "name": "Peter Parker",
    "phone": "3432434234",
    "email": "peter.parker@marvel.com"
}'
```

### **Response:**

* **200 OK:** A JSON object containing provided information of carrier contacts.
* **400 Bad Request:** If required parameters are missing or invalid.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been added to your user.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

200 OK – Contact Created Successfully

```json
{
  "contact": {
    "id": "bd849e72-09f0-4d19-8b20-e227cd4ef455",
    "name": "Peter Parker",
    "phone": "3432434234",
    "email": "peter.parker@marvel.com"
  }
}
```

400 Bad Request

Returned when:

* `usdot` is missing.
* `usdot` is malformed.
* `usdot` is provided, but all of `name`, `phone`, and `email` are null.
* `usdot` is provided, but all of `name`, `phone`, and `email` are empty strings.

```json
{
    "detail": "Missing required field: usdot"
}
```

```json
{
    "detail": "Value error, At least one of name, email, or phone must be provided."
}
```

{% code expandable="true" %}

```json
{
    "detail": "Value error, usdot must be at most 9 digits."
}
```

{% endcode %}

403 Forbidden

```json
{
    "detail": "User not allowed to access this endpoint"
}
```

## Create an onboarded carrier contact

> Creates a new onboarded carrier contact for the authenticated customer. Requires a valid JWT token and the appropriate permission. The \`usdot\` value must contain digits only, be greater than zero, and be at most 9 digits after normalization.<br>

```json
{"openapi":"3.0.3","info":{"title":"Onboarded Carrier Contacts API","version":"1.0.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"AccessTokenAuth":[],"ApiKeyAuth":[]}],"components":{"securitySchemes":{"AccessTokenAuth":{"type":"apiKey","in":"header","name":"Access-Token","description":"JWT provided directly in the Access-Token header. No \"Bearer\" prefix.\n"}}},"paths":{"/onboarded-carrier/contacts":{"post":{"summary":"Create an onboarded carrier contact","description":"Creates a new onboarded carrier contact for the authenticated customer. Requires a valid JWT token and the appropriate permission. The `usdot` value must contain digits only, be greater than zero, and be at most 9 digits after normalization.\n","tags":["Onboarded Carriers"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["usdot"],"properties":{"usdot":{"type":"string","description":"Carrier USDOT number. Must contain digits only, be greater than zero, and be at most 9 digits. Leading zeroes are normalized before persistence.\n","minLength":1,"maxLength":9,"pattern":"^[0-9]+$"},"name":{"type":"string","nullable":true,"description":"Contact name."},"phone":{"type":"string","nullable":true,"description":"Contact phone number."},"email":{"type":"string","nullable":true,"description":"Contact email address."}}}}}},"responses":{"200":{"description":"Contact created successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"contact":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"}}}}}}}},"400":{"description":"Bad Request – Missing or invalid fields.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"401":{"description":"Unauthorized – Invalid or missing Access-Token.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"403":{"description":"Forbidden – The user lacks required permission.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}}}}}}}
```


# Get Onboarded Carriers

This endpoint allows external systems to retrieve onboarded carrier contacts configured for the authenticated customer.

**Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

#### Permissions <a href="#permissions" id="permissions"></a>

The `external-api-get-onboarded-carrier-contact` permission is required to access this endpoint.

#### **Endpoint** <a href="#endpoint" id="endpoint"></a>

* **URL:** `https://api.genlogs.io/onboarded-carrier/contacts`
* **Method:** GET

#### **Headers** <a href="#headers" id="headers"></a>

* **Access-Token**: (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.

#### **Request Body:** <a href="#request-body" id="request-body"></a>

* **usdot\_number** (string, optional): Carrier USDOT number or numbers comma separated. Must be a non-empty value.
* **page** (string, optional): Expected page to be listed.
* **page\_size** (string, optional): Amount of items per page

#### Request Example: <a href="#request-example" id="request-example"></a>

```sh
curl --location 'https://api.genlogs.io/onboarded-carrier/contacts?page=4&page_size=2' \
--header 'access-token: <your-access-token>' \
--header 'x-api-key: <your-x-api-key>'
```

#### **Response:** <a href="#response" id="response"></a>

* **200 OK:** A JSON object containing the information of carrier contacts.
* **400 Bad Request:** If the provided parameters are malformed or invalid.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been added to your user.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

#### **Response Body:** <a href="#response-body" id="response-body"></a>

200 OK – Contacts listed Successfully

```json
{
  "contacts": [
    {
      "contact_id": "00-11-22-33-44",
      "dot_number": "123456",
      "customer_id": 3,
      "contact_name": "John",
      "contact_email": "john@email.com",
      "contact_phone": "(555) 555-5555",
      "contact_source": "GENLOGS"
    },
    {
      "contact_id": "11-22-33-44-55",
      "dot_number": "765432",
      "customer_id": 3,
      "contact_name": "Mike",
      "contact_email": "mike@email.com",
      "contact_phone": "(555) 555-5566",
      "contact_source": "GENLOGS"
    }
  ],
  "pagination": {
    "page_size": 2,
    "current_page": 4,
    "total_pages": 10
  }
}
```

400 Bad RequestReturned when:

* `usdot_number` is invalid, empty or equal to zero
* `page` value is out of bounds or not a valid integer
* `page_size` value is out of bounds or not a valid integer

```json
{
    "detail": "usdot_number cannot be empty"
}
```

```json
{
    "detail": "page 2 is out of range. Maximum page is 1"
}
```

403 Forbidden

```json
{
  "detail": "User not allowed to access this endpoint"
}
```

## Retrieve onboarded carrier contacts

> Returns a paginated list of onboarded carrier contacts for the authenticated customer. Only contacts belonging to the customer identified in the JWT are returned. Requires the external-api-get-onboarded-carrier-contact permission.<br>

```json
{"openapi":"3.0.3","info":{"title":"Onboarded Carrier Contacts API","version":"1.0.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"Access-Token":[],"X-Api-Key":[]}],"components":{"securitySchemes":{"Access-Token":{"type":"apiKey","in":"header","name":"Access-Token","description":"JWT provided directly in the Access-Token header.\n"}}},"paths":{"/onboarded-carrier/contacts":{"get":{"summary":"Retrieve onboarded carrier contacts","description":"Returns a paginated list of onboarded carrier contacts for the authenticated customer. Only contacts belonging to the customer identified in the JWT are returned. Requires the external-api-get-onboarded-carrier-contact permission.\n","tags":["Onboarded Carriers"],"parameters":[{"name":"page","in":"query","required":false,"description":"Page number of results to return.","schema":{"type":"integer","minimum":1,"default":1}},{"name":"page_size","in":"query","required":false,"description":"Number of results per page (max 200).","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"usdot_number","in":"query","required":false,"description":"USDOT number(s) to filter by. Supports a single value or a comma-separated list.\n","schema":{"type":"string"}}],"responses":{"200":{"description":"Onboarded carrier contacts retrieved successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"contacts":{"type":"array","description":"List of onboarded carrier contacts.","items":{"type":"object","properties":{"contact_id":{"type":"string","format":"uuid","description":"Unique identifier of the onboarded carrier contact."},"dot_number":{"type":"string","description":"USDOT number associated with the carrier."},"customer_id":{"type":"integer","description":"Identifier of the customer that owns the contact."},"contact_name":{"type":"string","description":"Full name of the contact."},"contact_email":{"type":"string","description":"Email address of the contact."},"contact_phone":{"type":"string","description":"Phone number of the contact."},"contact_source":{"type":"string","description":"Source of the onboarded contact record."}}}},"pagination":{"type":"object","description":"Pagination metadata.","properties":{"page_size":{"type":"integer","description":"Number of results per page."},"current_page":{"type":"integer","description":"Current page number."},"total_pages":{"type":"integer","description":"Total number of available pages."}}}}}}}},"400":{"description":"Bad Request – Invalid query parameters.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"401":{"description":"Unauthorized – Invalid or missing authentication headers.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"object","properties":{"message":{"type":"string"},"subcode":{"type":"string"}}}}}}}},"403":{"description":"Forbidden – User does not have required permission.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"type":"string"}}}}}}}}}
```


# Update Onboarded Carrier

Update an onboarded carrier contact associated with the specific contact\_id. This endpoint allows customers to update their own validated contact information.

### **Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### Permissions

The `external-api-update-onboarded-carrier-contact` permission is required to access this endpoint.

### **Endpoint**

* **URL:**  `https://api.genlogs.io/onboarded-carrier/contacts/{contact_id}`
* **Method:** `PATCH`

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **X-Api-Key** (string, required): The API key provided by GenLogs.

### Path Params

* **contact\_id** (string, required): Existent contact ID, to de updated.

### **Request Body:**

* **name** (string, optional): Contact name.&#x20;
* **phone** (string, optional): Contact phone number
* **email** (string, optional): Contact email address.

### Request Example:

```shell
curl --location --request PATCH 'https://api.genlogs.io/onboarded-carrier/contacts/ca387122-4153-418b-82df-03008cc9af9b' \
--header 'access-token: <your-api-access-token>' \
--header 'x-api-key: <your-x-api-key>' \
--header 'Content-Type: application/json' \
--data '{
    "email": "peter_parker@test_email.com",
    "name": "Peter Parker",
    "phone": "3432434234"
}'
```

### **Response:**

* **200 OK:** A JSON object containing updated information of carrier contact.
* **400 Bad Request:** If required parameters are missing or invalid.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been added to your user.
* **404 Not Found**: If the provided `contact_id` doesn't exist or is not created.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

200 OK – Contact Created Successfully

```json
{
  "contact": {
    "contact_id": "bd849e72-09f0-4d19-8b20-e227cd4ef455",
    "name": "Peter Parker",
    "phone": "3432434234",
    "email": "peter.parker@marvel.com"
  }
}
```

400 Bad Request

Returned when:

* All of `name`, `phone`, and `email` are null.
* `A`ll of `name`, `phone`, and `email` are empty strings.
* All the provided values are exactly the same as stored

```json
{
    "detail": "Value error, at least one of name, email, or phone must be provided for update."
}
```

401 Unauthorized

* When access-token is missing or expired

```json
{
    "detail": "Token is missing!"
}
```

403 Forbidden

```json
{
    "detail": "User not allowed to access this endpoint"
}
```

404 Not Found

```json
{
    "detail": "Preferred carrier contact not found."
}
```

## Update an onboarded carrier contact

> Updates an existing onboarded carrier contact for the authenticated customer. Requires a valid JWT token and the appropriate permission. Only the fields provided in the request body will be updated. USDOT updates are not supported by this endpoint; including \`usdot\` in the PATCH body returns Bad Request before any persistence operation.<br>

```json
{"openapi":"3.0.3","info":{"title":"Onboarded Carrier Contacts API","version":"1.0.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"AccessTokenAuth":[],"ApiKeyAuth":[]}],"components":{"securitySchemes":{"AccessTokenAuth":{"type":"apiKey","in":"header","name":"Access-Token","description":"JWT provided directly in the Access-Token header. No \"Bearer\" prefix.\n"}}},"paths":{"/onboarded-carrier/contacts/{contact_id}":{"patch":{"summary":"Update an onboarded carrier contact","description":"Updates an existing onboarded carrier contact for the authenticated customer. Requires a valid JWT token and the appropriate permission. Only the fields provided in the request body will be updated. USDOT updates are not supported by this endpoint; including `usdot` in the PATCH body returns Bad Request before any persistence operation.\n","tags":["Onboarded Carriers"],"parameters":[{"name":"contact_id","in":"path","required":true,"description":"Unique identifier of the contact to update.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Fields to update. At least one must be provided. `usdot` is not accepted in PATCH requests.\n","properties":{"name":{"type":"string","nullable":true,"description":"Contact name."},"email":{"type":"string","nullable":true,"description":"Contact email."},"phone":{"type":"string","nullable":true,"description":"Contact phone number."}},"minProperties":1}}}},"responses":{"200":{"description":"Contact updated successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"contact":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"}}}}}}}},"400":{"description":"Bad Request – Missing or invalid fields.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"401":{"description":"Unauthorized – Invalid or missing Access-Token.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"403":{"description":"Forbidden – The user lacks required permission or does not own the contact.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"404":{"description":"Contact not found.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}}}}}}}
```


# Delete Onboarded Carrier

Delete an onboarded carrier contact associated with the specific contact\_id. This endpoint allows customers to remove their own validated contact information.

### **Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### Permissions

The `external-api-delete-onboarded-carrier-contact` permission is required to access this endpoint.

### **Endpoint**

* **URL:**  `https://api.genlogs.io/onboarded-carrier/contacts/{contact_id}`
* **Method:** `DELETE`

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **X-Api-Key** (string, required): The API key provided by GenLogs.

### Path Params

* **contact\_id** (string, UUID format,  required): Existent contact ID, to be deleted.

### Request Example:

```shell
curl --location --request DELETE 'https://api.genlogs.io/onboarded-carrier/contacts/<contact_id>' \
--header 'access-token: <your-api-access-token>' \
--header 'x-api-key: <your-x-api-key>' \
--header 'Content-Type: application/json' \
```

### **Response:**

* **200 OK:** A JSON object containing the information of the deleted carrier contact.
* **400 Bad Request:** If required parameters are missing or invalid.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been added to your user.
* **404 Not Found**: If the provided `contact_id` doesn't exist or is not created.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

200 OK – Contact Deleted Successfully

```json
{
    "contact": {
        "contact_name": "some_name",
        "phone_number": "1-222-333-444",
        "email_address": "some_user@testemail.com",
        "usdot_number": "1324354657",
        "contact_id": <contact_id>,
        "customer_id": <customer_id>,
    },
    "deleted": true
}
```

400 Bad Request

Returned when:

* The provided contact id is malformed or missing

```json
{
    "detail": "Error deleting onboarded carrier contact: {message}"
}
```

401 Unauthorized

* When access-token is missing or expired

```json
{
    "detail": "Token is missing!"
}
```

```json
{
    "detail": "Token is expired!"
}
```

403 Forbidden

```json
{
    "detail": "User not allowed to access this endpoint"
}
```

404 Not Found

```json
{
    "detail": "Preferred carrier contact not found."
}
```

## Delete an onboarded carrier contact

> Deletes an existing onboarded carrier contact for the authenticated customer. Requires a valid JWT token and the appropriate permission. The contact must belong to the authenticated customer.<br>

```json
{"openapi":"3.0.3","info":{"title":"Onboarded Carrier Contacts API","version":"1.0.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"AccessTokenAuth":[],"ApiKeyAuth":[]}],"paths":{"/onboarded-carrier/contacts/{contact_id}":{"delete":{"summary":"Delete an onboarded carrier contact","description":"Deletes an existing onboarded carrier contact for the authenticated customer. Requires a valid JWT token and the appropriate permission. The contact must belong to the authenticated customer.\n","tags":["Onboarded Carriers"],"parameters":[{"name":"contact_id","in":"path","required":true,"description":"Unique identifier of the contact to delete.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Contact deleted successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"contact":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean"}}}}}}}},"400":{"description":"Bad Request – Invalid contact identifier.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"401":{"description":"Unauthorized – Invalid or missing Access-Token.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"403":{"description":"Forbidden – The user lacks required permission or does not own the contact.\n","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"404":{"description":"Contact not found.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}}}}}}}
```


# Create Onboarded Carriers Bulk

### **Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### Permissions

The `external-api-create-onboarded-carrier-contact` permission is required to access this endpoint.

### **Endpoint**

* **URL:**  `https://api.genlogs.io/onboarded-carrier/bulk/contacts`
* **Method:** `POST`

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **X-Api-Key** (string, required): The API key provided by GenLogs.

### Request body

* **contacts** (list, object,  required): List of contacts to be created. Including:
  * **usdot** (string, required): Carrier USDOT number. Must contain digits only, be greater than zero, and be at most 9 digits.
  * **name** (string, optional): Contact name.&#x20;
  * **phone** (string, optional): Contact phone number
  * **email** (string, optional): Contact email address.

### Request Example:

```shell
curl --location --request POST 'https://api.genlogs.io/onboarded-carrier/bulk/contacts' \
--header 'access-token: <your-api-access-token>' \
--header 'x-api-key: <your-x-api-key>' \
--header 'Content-Type: application/json' \
--data-raw '{
    "contacts": [
        {
            "usdot": "123456789",
            "name": "Peter Parker",
            "phone": "3432434234",
            "email": "peter.parker@marvel.com"
        },
        {
            "usdot": "234567890",
            "name": "Mary Jane",
            "phone": "5423123456",
            "email": "mary.jane@marvel.com"
        }
    ]
}'
```

### **Response:**

* **200 OK:** A JSON object containing two lists for:
  * **Success**: created carrier contact(s) with relevant information including `usdot`, `name` and `id`.
  * **Failed**: failed creation with `index` and `reason`.
* **400 Bad Request:** If required parameters are missing or invalid.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been added to your user.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

200 OK – Contacts Deleted Successfully

```json
{
    "contacts": [
        {
            "usdot": "123456789",
            "name": "Peter Parker",
            "phone": "3432434234",
            "email": "peter.parker@marvel.com"
        },
        {
            "usdot": "234567890",
            "name": "Mary Jane",
            "phone": "5423123456",
            "email": "mary.jane@marvel.com"
        }
    ]
}
```

400 Bad Request

Returned when:

* The provided contacts list is malformed or missing
* Malformed `usdot`  number

```json
{
    "detail": "Missing required field: contacts"
}
```

```json
{
    "detail": "All contacts failed to be created"
}
```

```json
{
    "detail": "Value error, usdot_number must contain only digits."
}
```

```json
{
    "detail": "contacts list must not be empty"
}
```

401 Unauthorized

* When access-token is missing or expired

```json
{
    "detail": "Token is missing!"
}
```

```json
{
    "detail": "Token is expired!"
}
```

403 Forbidden

```json
{
    "detail": "User not allowed to access this endpoint"
}
```

404 Not Found

## Bulk create onboarded carrier contacts

> Creates multiple onboarded carrier contacts for the authenticated customer in a single request. Each contact entry is validated using the same rules as the single-contact create flow. At least one contact must be valid for the operation to succeed. The operation follows the same authorization, repository, caching, and creation logic as the single-contact create flow. Each \`usdot\` value must contain digits only, be greater than zero, and be at most 9 digits after normalization.<br>

```json
{"openapi":"3.0.3","info":{"title":"Onboarded Carrier Contacts API","version":"1.1.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"AccessTokenAuth":[],"ApiKeyAuth":[]}],"paths":{"/onboarded-carrier/bulk/contacts":{"post":{"summary":"Bulk create onboarded carrier contacts","description":"Creates multiple onboarded carrier contacts for the authenticated customer in a single request. Each contact entry is validated using the same rules as the single-contact create flow. At least one contact must be valid for the operation to succeed. The operation follows the same authorization, repository, caching, and creation logic as the single-contact create flow. Each `usdot` value must contain digits only, be greater than zero, and be at most 9 digits after normalization.\n","tags":["Onboarded Carriers"],"requestBody":{"required":true,"description":"List of onboarded carrier contact definitions to create. The contacts array must be non-empty.\n","content":{"application/json":{"schema":{"type":"object","required":["contacts"],"properties":{"contacts":{"type":"array","minItems":1,"description":"List of contacts to create.","items":{"type":"object","required":["usdot"],"properties":{"usdot":{"type":"string","description":"Carrier USDOT number. Must contain digits only, be greater than zero, and be at most 9 digits. Leading zeroes are normalized before persistence.\n","minLength":1,"maxLength":9,"pattern":"^[0-9]+$"},"name":{"type":"string","nullable":true,"description":"Contact name."},"phone":{"type":"string","nullable":true,"description":"Contact phone number."},"email":{"type":"string","nullable":true,"description":"Contact email address."}}}}}}}}},"responses":{"200":{"description":"Contacts processed successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"created_contacts":{"type":"array","description":"List of successfully created contacts.","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"usdot":{"type":"string"},"name":{"type":"string"}}}},"failed_contacts":{"type":"array","description":"Per-item errors for contacts that were not created.","items":{"type":"object","properties":{"index":{"type":"integer","description":"Index of the contact in the original payload."},"error":{"type":"string","description":"Human-readable error message for this item."}}}}}}}}},"400":{"description":"Bad Request – Invalid request body or all items failed.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"401":{"description":"Unauthorized – Invalid or missing Access-Token.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"403":{"description":"Forbidden – Missing required permission.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}}}}}}}
```


# Delete Onboarded Carrier Bulk

### **Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### Permissions

The `external-api-delete-onboarded-carrier-contact` permission is required to access this endpoint.

### **Endpoint**

* **URL:**  `https://api.genlogs.io/onboarded-carrier/bulk/contacts`
* **Method:** `DELETE`

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **X-Api-Key** (string, required): The API key provided by GenLogs.

### Request body

* **contact\_ids** (list, UUID format str,  required): Existent contact ID list, to be deleted.

### Request Example:

```shell
curl --location --request DELETE 'https://api.genlogs.io/onboarded-carrier/bulk/contacts' \
--header 'access-token: <your-api-access-token>' \
--header 'x-api-key: <your-x-api-key>' \
--header 'Content-Type: application/json' \
--data '{
    "contact_ids": [
        "11111111-2222-3333-4444-555555555555",
        "11111111-2222-3333-4444-555555555556",
        "11111111-2222-3333-4444-555555555557"
    ]
}'
```

### **Response:**

* **200 OK:** A JSON object containing a list of deleted carrier contact(s).
* **400 Bad Request:** If required parameters are missing or invalid.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been added to your user.
* **404 Not Found**: If one or more of the provided `contact_ids` doesn't exist or are not created.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

200 OK – Contacts Deleted Successfully

```json
{
    "contacts": [
        {"id": "11111111-2222-3333-4444-555555555555", "deleted": true},
        {"id": "11111111-2222-3333-4444-555555555556", "deleted": true},
        {"id": "11111111-2222-3333-4444-555555555557", "deleted": true} 
    ]
}
```

400 Bad Request

Returned when:

* The provided contact id list is malformed or missing

```json
{
    "detail": "Missing required field: contact_ids"
}
```

```json
{
    "detail": "Value error, contact_ids must not be empty"
}
```

401 Unauthorized

* When access-token is missing or expired

```json
{
    "detail": "Token is missing!"
}
```

```json
{
    "detail": "Token is expired!"
}
```

403 Forbidden

```json
{
    "detail": "User not allowed to access this endpoint"
}
```

404 Not Found

```json
{
    "detail": "One or more contacts were not found or do not belong to the customer."
}
```

## Bulk delete onboarded carrier contacts

> Deletes multiple onboarded carrier contacts for the authenticated customer in a single request. All provided contact IDs must exist and belong to the authenticated customer. The operation follows the same authorization, repository, caching, and deletion logic as the single-contact delete flow.<br>

```json
{"openapi":"3.0.3","info":{"title":"Onboarded Carrier Contacts API","version":"1.1.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"AccessTokenAuth":[],"ApiKeyAuth":[]}],"paths":{"/onboarded-carrier/bulk/contacts":{"delete":{"summary":"Bulk delete onboarded carrier contacts","description":"Deletes multiple onboarded carrier contacts for the authenticated customer in a single request. All provided contact IDs must exist and belong to the authenticated customer. The operation follows the same authorization, repository, caching, and deletion logic as the single-contact delete flow.\n","tags":["Onboarded Carriers"],"requestBody":{"required":true,"description":"List of onboarded carrier contact identifiers to delete. At least one contact_id must be provided.\n","content":{"application/json":{"schema":{"type":"object","required":["contact_ids"],"properties":{"contact_ids":{"type":"array","minItems":1,"description":"List of contact UUIDs to delete.","items":{"type":"string","format":"uuid"}}}}}}},"responses":{"200":{"description":"Contacts deleted successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"contacts":{"type":"array","description":"List of deleted contacts.","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean"}}}}}}}}},"400":{"description":"Bad Request – Invalid request body.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"401":{"description":"Unauthorized – Invalid or missing Access-Token.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"403":{"description":"Forbidden – Missing required permission.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"404":{"description":"One or more contacts not found or not owned by the customer.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}}}}}}}
```


# Carrier FMCSA Profile

## Carrier Profile (FMCSA) Endpoint

Retrieve a complete FMCSA carrier profile for a single carrier in one request. The endpoint aggregates operating status, authority history, safety (OOS / ISS / BASIC scores), insurance, violations, crashes, and fleet & driver summaries into a single carrier-level payload, with optional VIN-level detail.

### Authentication

Include your `Access-Token` in the header of your requests. Include your `x-api-key`, the API key provided by GenLogs. This header must be included in the request.

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

### Permissions

No special permission is required to call this endpoint. A valid External API token returns the full base profile (operating status, authority history, safety/OOS, insurance, violations, crashes, and fleet & drivers).

Two **optional** permissions unlock additional data. They are independent — a token may hold either, both, or neither.

| Permission                       | Unlocks                                                                 | Behavior when absent                                                                           |
| -------------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `external-api-carrier-iss-score` | The detailed `iss_basics` section (ISS score detail + BASIC breakdown). | `iss_basics` is `null` and an `errors.iss_basics` entry of type `PermissionError` is returned. |

> **Note on the ISS score.** The summary ISS score (`oos.iss_score`) is **always** included in the response and is **not** gated. The `external-api-carrier-iss-score` permission only controls the detailed `iss_basics` breakdown section.

### Endpoint

**URL:** `https://api.genlogs.io/carrier/profile/fmcsa` **Method:** `GET`

#### Headers

| Header         | Required | Description                                                        |
| -------------- | -------- | ------------------------------------------------------------------ |
| `Access-Token` | Yes      | The access token obtained from the "Create Access Token" endpoint. |
| `x-api-key`    | Yes      | The API key provided by GenLogs.                                   |

#### Query Parameters

| Parameter      | Type   | Required | Description                                                                                                                                                                              |
| -------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `usdot_number` | string | Yes      | Carrier USDOT number. If missing or empty, the request returns `400`.                                                                                                                    |
| `vin`          | string | No       | A vehicle VIN. When supplied, the `vin_details` section is populated with inspection, crash, and violation history for that VIN. When omitted, `vin_details` is `null` (no eager fetch). |

#### Request Example

```bash
curl --location \
  "https://api.genlogs.io/carrier/profile/fmcsa?usdot_number=445219" \
  --header "x-api-key: YOUR_API_KEY" \
  --header "Access-Token: YOUR_ACCESS_TOKEN"
```

### Response

* **200 OK:** A JSON object containing the aggregated carrier profile. A `200` is returned even when some sections fail — see Partial failures.
* **400 Bad Request:** `usdot_number` is missing or empty.
* **401 Unauthorized:** The `Access-Token` is missing or invalid.
* **403 Forbidden:** The `Access-Token` is expired.
* **500 Internal Server Error:** An unexpected error occurred while assembling the profile.

#### Response Body

The top-level object is a `CarrierFMCSAProfile`. Each section resolves independently; a section that fails or is permission-gated is `null`, with details in `errors`.

| Field               | Type   | Description                                                                                                                               |
| ------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `dot_number`        | string | The carrier USDOT number the profile was built for.                                                                                       |
| `operating_status`  | object | DOT status & safety rating, FMCSA authorizations (common / contract / broker), MCS-150 details, and active certifications.                |
| `authority_history` | object | Carrier history snapshots (power units, drivers, mileage over time) and authority action history.                                         |
| `oos`               | object | Full safety payload: summary ISS score, BASIC scores, major/severe violation counts, crash summary, and OOS rates. See `oos`.             |
| `insurance`         | object | Active insurance (BIPD, cargo, bond) and insurance-history summary.                                                                       |
| `iss_basics`        | object | Detailed ISS + BASIC breakdown (header, tab summary, time-series chart, violation summary & history). Permission-gated. See `iss_basics`. |
| `violations`        | object | Violation counts by severity bucket and per-violation rows.                                                                               |
| `crashes`           | object | Crash counts by severity and per-crash rows.                                                                                              |
| `fleet_and_drivers` | object | Fleet overview (tractors / trailers), driver summary, cargo carried, and fleet age.                                                       |
| `vin_details`       | object | VIN-level inspection, crash, and violation history. Only present when the `vin` query parameter is supplied; otherwise `null`.            |
| `errors`            | object | Map of section name → `{ message, type }` for any section that failed or was permission-gated. `null` when no section errored.            |

**`oos`**

The safety section. The summary `iss_score` is always present.

| Field                         | Type   | Description                                                                                                                                                                                                                      |
| ----------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `iss_score`                   | number | Summary Inspection Selection System (ISS) score. Always returned.                                                                                                                                                                |
| `basic_scores`                | object | The seven FMCSA BASIC categories (`unsafe_driving`, `hours_of_service`, `driver_fitness`, `controlled_substances`, `vehicle_maintenance`, `hazmat_related`, `crash_indicator`), each with `score`, `measure`, and `is_escalate`. |
| `major_and_severe_violations` | object | `{ most_severe_violations_count, major_violations_count }`.                                                                                                                                                                      |
| `crash_information`           | object | `{ crash_count, injuries, fatalities }`.                                                                                                                                                                                         |
| `oos_scores`                  | object | Out-of-service rates: `overall`, `driver`, `vehicle`, and `hazmat`. Each detail entry has `percent_oos`, `total_oos`, `total_inspected`, and `national_avg`.                                                                     |

**`iss_basics`**

The detailed ISS + BASIC section. Present only when the token holds `external-api-carrier-iss-score`.

| Field                | Type   | Description                                                                                                                        |
| -------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `header`             | object | `{ score, status, measure, recommendation, show_score }` — the headline ISS figure and recommendation.                             |
| `tab_summary`        | array  | Per-BASIC summary rows: `{ category, title, percentage, measure, status, is_escalate }`.                                           |
| `chart`              | object | ISS time series: `data`, `labels`, `date_range`, `group_median`, `may_measure`, `point_classifications`, `has_established_median`. |
| `violation_summary`  | array  | Violation summary rows: `{ weight, category, total, out_of_service }`.                                                             |
| `violation_history`  | array  | Individual violation entries (date, code, description, weights, etc.).                                                             |
| `current_fleet_vins` | array  | Normalized VINs currently in the carrier's fleet.                                                                                  |

#### Example Response

> Illustrative example for `usdot_number=445219`, using a token that holds `external-api-carrier-iss-score` . Values are representative.

```json
{
  "dot_number": "445219",
  "operating_status": {
    "dot_status": {
      "rating_date": "2021-08-12",
      "dot_status": "ACTIVE",
      "dot_safety_rating": "SATISFACTORY"
    },
    "authorization": {
      "common_authority": "ACTIVE",
      "common_authority_date": "2009-03-01",
      "contract_authority": "ACTIVE",
      "contract_authority_date": "2009-03-01",
      "broker_authority": "NONE",
      "broker_authority_date": null
    },
    "mc_150_details": {
      "last_update": "2024-11-02",
      "operations_classification": ["AUTHORIZED FOR HIRE"],
      "transport_hazmat": "N"
    },
    "mc_150_carrier_history": { "last_snapshot_date": "2025-05-01" },
    "active_certifications": { "active_certifications": ["Common", "Contract"] }
  },
  "authority_history": {
    "carrier_history": [
      {
        "snapshot_date": "2025-05-01",
        "mcs150_date": "2024-11-02",
        "power_units": 42,
        "drivers": 40,
        "mileage": 5120000,
        "power_units_change_pct": 5.0,
        "drivers_change_pct": 2.6,
        "mileage_change_pct": 3.1
      }
    ],
    "authority_history": [
      {
        "authority_type": "Common",
        "original_action": "GRANTED",
        "action_date": "2009-03-01",
        "disposition_action": null,
        "disposition_date": null
      }
    ],
    "authority_history_count": 1
  },
  "oos": {
    "iss_score": 62,
    "basic_scores": {
      "unsafe_driving": { "score": 35, "measure": 1.2, "is_escalate": false },
      "hours_of_service": { "score": 48, "measure": 2.0, "is_escalate": false },
      "driver_fitness": { "score": 12, "measure": 0.3, "is_escalate": false },
      "controlled_substances": { "score": 0, "measure": 0.0, "is_escalate": false },
      "vehicle_maintenance": { "score": 71, "measure": 3.4, "is_escalate": true },
      "hazmat_related": { "score": null, "measure": null, "is_escalate": null },
      "crash_indicator": { "score": 22, "measure": 0.8, "is_escalate": false }
    },
    "major_and_severe_violations": {
      "most_severe_violations_count": 3,
      "major_violations_count": 11
    },
    "crash_information": { "crash_count": 2, "injuries": 1, "fatalities": 0 },
    "oos_scores": {
      "overall": { "percent_oos": 18.5, "total_oos": 12, "total_inspected": 65 },
      "driver": { "percent_oos": 4.1, "total_oos": 2, "total_inspected": 49, "national_avg": 5.5 },
      "vehicle": { "percent_oos": 24.3, "total_oos": 10, "total_inspected": 41, "national_avg": 22.0 },
      "hazmat": { "percent_oos": 0.0, "total_oos": 0, "total_inspected": 0, "national_avg": 4.5 }
    },
  },
  "insurance": {
    "active_insurance": {
      "boc_3_filing_company_name": "Acme Process Agents LLC",
      "bipd_primary_status": "ACTIVE",
      "bipd_primary_insurance_on_file": "1000000",
      "cargo_status": "ACTIVE",
      "cargo_insurance_on_file": "100000",
      "bond_status": "NONE",
      "bond_insurance_on_file": null
    },
    "insurance_history": { "same_carrier_3plus_years": true, "count": 4 }
  },
  "iss_basics": {
    "header": {
      "score": "62",
      "status": "Optional",
      "measure": "ISS-2",
      "recommendation": "Optional",
      "show_score": true
    },
    "tab_summary": [
      {
        "category": "vehicle_maintenance",
        "title": "Vehicle Maintenance",
        "percentage": "71%",
        "measure": "3.40",
        "status": "Alert",
        "is_escalate": true
      }
    ],
    "chart": {
      "data": [58.0, 60.0, 62.0],
      "labels": ["2025-03", "2025-04", "2025-05"],
      "date_range": { "start_date": "2025-03-01", "end_date": "2025-05-01" },
      "group_median": [55.0, 56.0, 57.0],
      "may_measure": 62.0,
      "point_classifications": null,
      "has_established_median": true
    },
    "violation_summary": [
      { "weight": "7", "category": "Vehicle Maint.", "total": "10", "out_of_service": "10" }
    ],
    "violation_history": [],
    "current_fleet_vins": ["1FUJGLDR8CSBP1234", "3AKJGLDR8CSBP5678"],
  },
  "violations": {
    "major_violations_count": 11,
    "most_severe_violations_count": 3,
    "less_severe_violations_count": 27,
    "rows": [
      {
        "date": "2025-02-14",
        "number": "INS123456",
        "vin": "1FUJGLDR8CSBP1234",
        "violation_description": "Brake hose/tubing chafing and/or kinking",
        "state": "OH",
        "plate_number": "PXY1234",
        "plate_state": "OH",
        "severity_weight": 4,
        "severity_bucket": "major"
      }
    ]
  },
  "crashes": {
    "major_crashes_count": 2,
    "most_severe_crashes_count": 0,
    "rows": [
      {
        "date": "2024-09-03",
        "report_number": "OH20240903",
        "vin": "1FUJGLDR8CSBP1234",
        "location": "I-70 MM 110",
        "state": "OH",
        "plate_number": "PXY1234",
        "plate_state": "OH",
        "fatalities": 0,
        "injury": 1,
        "towaway": "Y",
        "preventable": "U",
        "severity_weight": 2,
        "severity_bucket": "major"
      }
    ]
  },
  "fleet_and_drivers": {
    "fleet_overview": {
      "total_fleet": 64,
      "tractors": { "total_count": 42, "owned_count": 38, "leased_count": 4 },
      "trailers": { "total_count": 22, "owned_count": 20, "leased_count": 2 }
    },
    "drivers": { "driver_count": 40, "cdl_total_miles": 5120000 },
    "cargo_carried": ["General Freight", "Building Materials"],
    "fleet_age": {
      "total_tractor_count": 42,
      "avg_age_years": 6,
      "oldest_unit_year": 2012,
      "newest_unit_year": 2024
    }
  },
  "vin_details": null,
  "errors": null
}
```

### Partial failures

Each section is resolved independently and concurrently. If a section fails, its field is set to `null` and a structured entry is added to the `errors` map; the request still returns `200`. The `type` reflects the cause (for example `TimeoutError`, `NotFoundError`, or `PermissionError`).

```json
{
  "dot_number": "445219",
  "operating_status": { "...": "..." },
  "insurance": null,
  "errors": {
    "insurance": { "message": "timeout", "type": "TimeoutError" }
  }
}
```

#### Permission-gated example

When the token lacks `external-api-carrier-iss-score`, the `iss_basics` section is withheld and reported in `errors`. The summary `oos.iss_score` is still returned.

```json
{
  "dot_number": "445219",
  "oos": { "iss_score": 62, "...": "..." },
  "iss_basics": null,
  "errors": {
    "iss_basics": {
      "message": "Missing required permission: external-api-carrier-iss-score",
      "type": "PermissionError"
    }
  }
}
```

### Status codes

| Code  | Meaning                                                                              |
| ----- | ------------------------------------------------------------------------------------ |
| `200` | Success — including partial responses where some sections are `null` (see `errors`). |
| `400` | `usdot_number` is missing or empty.                                                  |
| `401` | `Access-Token` is missing or invalid.                                                |
| `403` | `Access-Token` is expired.                                                           |
| `500` | Unexpected error while assembling the profile.                                       |


# Carrier Vetting Assessment

Search by a USDOT number and receive a vetting assessment (pass, needs review, fail) along with assessment details per rule.

### **Authentication**

* Include your **`Access-Token`** and **`x-api-key`** in the header of your requests.

### Permissions

The `external-api-compliance-rules` permission is required to access this endpoint.

### **Endpoint**

* **URL:**  `https://api.genlogs.io/compliance-rules`
* **Method:** GET

### **Request Parameters**

* **usdot\_number** (string, Required): The USDOT number corresponding to the carrier you would like to review.
* **usdot\_numbers** (string, Required): A comma separated string list with the USDOT numbers corresponding to the carriers you would like to review (if present `usdot_number` will be ignored).

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.&#x20;

### Request Example:

```bash
curl --location 'https://api.genlogs.io/compliance-rules?usdot_number=100000' \
--header 'access-token: <your-api-token>' \
--header 'x-api-key: <your-x-api-key>'
```

```bash
curl --location 'https://api.genlogs.io/compliance-rules?usdot_numbers=10000,20000,30000' \
--header 'access-token: <your-api-token>' \
--header 'x-api-key: <your-x-api-key>'
```

### **Response:**

* **200 OK:** A JSON object containing the vetting information for the provided carrier.
* **400 Bad Request:** If `usdot_number` or `usdot_numbers` required parameter is missing or invalid.
* **401 Unauthorized:** If the authentication credentials (**Access-Token**) is missing or incorrect.
* **403 Forbidden**: If the permission has not been set to your user.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

200 OK – Vetting information found for carrier when `usdot_number` is provided

{% code expandable="true" %}

```json
{
   "rules":[
      {
         "rule_result_description":"Carrier has been observed by GenLogs.",
         "status":"pass",
         "category":"GenLogs",
         "rule_order":1
      }
   ],
   "rule_status":{
      "pass":{
         "total":1
      },
      "fail":{
         "total":0
      },
      "review":{
         "total":0
      }
   }
}
```

{% endcode %}

200 OK - Vetting information found or not for carriers when `usdot_numbers` is provided

{% code expandable="true" %}

```json
{
  "results": [
    {
      "usdot_number": "40717",
      "found": false
    },
    {
      "usdot_number": "3888080",
      "found": true,
      "rules": [
        {
          "rule_result_description": "Carrier has NOT been observed by GenLogs.",
          "status": "fail",
          "category": "GenLogs",
          "rule_order": 1
        }
      ],
      "rule_status": {
        "pass": {
          "total": 24
        },
        "fail": {
          "total": 3
        },
        "review": {
          "total": 9
        }
      }
    }
  ]
}
```

{% endcode %}

400 Bad Request

Returned when:

* `usdot_number` is missing, empty, malformed or zero

```json
{
    "detail": "usdot_number is required"
}
```

```json
{
    "detail": "usdot_number must not be empty or zero"
}
```

```json
{
    "message": "Invalid usdot_number value(s): '000000'"
}
```

403 Forbidden

```json
{
    "detail": "User does not have the required permissions to access this resource"
}
```

404 Not Found

```json
{
    "message": "No vetting data found for usdot_number: 100000"
}
```

## Get carrier compliance rules by USDOT (single or batch)

> Returns carrier compliance rules for one or more USDOT numbers.\
> \- Single mode: provide \`usdot\_number\`. The response shape is a single\
> &#x20; object with \`rules\` and \`rule\_status\` and is fully backward compatible\
> &#x20; with the existing API.\
> \- Batch mode: provide \`usdot\_numbers\` as a comma-separated list. The\
> &#x20; response shape is an object with a \`results\` array where each item\
> &#x20; represents one USDOT and includes a \`found\` flag.\
> \
> When both \`usdot\_number\` and \`usdot\_numbers\` are provided, \`usdot\_numbers\` takes precedence and \`usdot\_number\` is ignored.\
> The maximum number of USDOT values allowed in \`usdot\_numbers\` is limited to 50. Requests that exceed this limit return HTTP 400.\
> Each batch result item uses \`found=false\` when no vetting data exists for that USDOT. In that case the item only contains \`usdot\_number\` and \`found\`. When \`found=true\`, \`rules\` and \`rule\_status\` are populated with the same structure as the single-USDOT response.\
> Examples:\
> \- Single:\
> &#x20; \`/compliance-rules?usdot\_number=1234567\`\
> \- Batch:\
> &#x20; \`/compliance-rules?usdot\_numbers=1234567,7654321\`<br>

```json
{"openapi":"3.0.3","info":{"title":"Customer Compliance Rules API","version":"1.0.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"Access-Token":[],"X-Api-Key":[]}],"components":{"securitySchemes":{"Access-Token":{"type":"apiKey","in":"header","name":"Access-Token","description":"JWT provided directly in the Access-Token header.\n"}},"schemas":{"CarrierRulesSingleResponse":{"type":"object","required":["rules","rule_status"],"additionalProperties":false,"properties":{"rules":{"type":"array","items":{"$ref":"#/components/schemas/CarrierRuleItem"}},"rule_status":{"$ref":"#/components/schemas/CarrierRuleStatusCounts"}}},"CarrierRuleItem":{"type":"object","required":["rule_result_description","status","category"],"additionalProperties":false,"properties":{"rule_result_description":{"type":"string"},"status":{"type":"string","description":"PASS / FAIL / REVIEW"},"category":{"type":"string"},"rule_order":{"type":"string"}}},"CarrierRuleStatusCounts":{"type":"object","required":["pass","fail","review"],"additionalProperties":false,"properties":{"pass":{"type":"object","required":["total"],"properties":{"total":{"type":"integer"}}},"fail":{"type":"object","required":["total"],"properties":{"total":{"type":"integer"}}},"review":{"type":"object","required":["total"],"properties":{"total":{"type":"integer"}}}}},"CarrierRulesBatchResponse":{"type":"object","required":["results"],"additionalProperties":false,"properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/CarrierRulesBatchResultItem"}}}},"CarrierRulesBatchResultItem":{"type":"object","required":["usdot_number","found"],"additionalProperties":false,"properties":{"usdot_number":{"type":"string"},"found":{"type":"boolean"},"rules":{"type":"array","items":{"$ref":"#/components/schemas/CarrierRuleItem"}},"rule_status":{"$ref":"#/components/schemas/CarrierRuleStatusCounts"}},"description":"Per-carrier result in a batch response. When found=false, the item only\ncontains usdot_number and found.\n"}}},"paths":{"/compliance-rules":{"get":{"summary":"Get carrier compliance rules by USDOT (single or batch)","description":"Returns carrier compliance rules for one or more USDOT numbers.\n- Single mode: provide `usdot_number`. The response shape is a single\n  object with `rules` and `rule_status` and is fully backward compatible\n  with the existing API.\n- Batch mode: provide `usdot_numbers` as a comma-separated list. The\n  response shape is an object with a `results` array where each item\n  represents one USDOT and includes a `found` flag.\n\nWhen both `usdot_number` and `usdot_numbers` are provided, `usdot_numbers` takes precedence and `usdot_number` is ignored.\nThe maximum number of USDOT values allowed in `usdot_numbers` is limited to 50. Requests that exceed this limit return HTTP 400.\nEach batch result item uses `found=false` when no vetting data exists for that USDOT. In that case the item only contains `usdot_number` and `found`. When `found=true`, `rules` and `rule_status` are populated with the same structure as the single-USDOT response.\nExamples:\n- Single:\n  `/compliance-rules?usdot_number=1234567`\n- Batch:\n  `/compliance-rules?usdot_numbers=1234567,7654321`\n","tags":["Compliance Rules"],"parameters":[{"name":"usdot_number","in":"query","required":false,"description":"Single USDOT number to evaluate. Ignored when `usdot_numbers` is also provided.\n","schema":{"type":"string"}},{"name":"usdot_numbers","in":"query","required":false,"description":"Comma-separated list of USDOT numbers for batch evaluation. When provided, this parameter takes precedence over `usdot_number`.\n","schema":{"type":"string"}}],"responses":{"200":{"description":"Compliance rules retrieved successfully (single or batch).\n- Single: single carrier response (rules + rule_status). - Batch: list of per-carrier results with `found` flags.\n","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/CarrierRulesSingleResponse"},{"$ref":"#/components/schemas/CarrierRulesBatchResponse"}]}}}},"400":{"description":"Bad Request – invalid input, missing required query parameters, or exceeding the maximum allowed number of USDOT values.\n","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"401":{"description":"Unauthorized – Invalid or missing Access-Token.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"object"}}}}}},"403":{"description":"Forbidden – Company user does not have vetting access permission.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"404":{"description":"Not Found – no vetting data exists for any of the requested USDOT numbers.\n","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"type":"string"}}}}}}}}}
```


# Update Customer Vetting Rule

### Authentication

Include your `Access-Token` and `x-api-key` in the header of your requests.

### Permissions

The `external-api-update-compliance-rules` permission is required to access this endpoint.

To retrieve the `customer_rule_id` before updating, use the List Customer Compliance Rules endpoint, which requires the `external-api-compliance-rules` permission.

### Endpoint

URL: `https://api.genlogs.io/customer-compliance-rules/{customer_rule_id}`\
Method: `PATCH`

Updates the status and/or parameter values of an existing customer compliance rule. At least one of `status` or `param_values` must be provided.

### Path Parameters

| Parameter          | Type          | Required | Description                                                  |
| ------------------ | ------------- | -------- | ------------------------------------------------------------ |
| `customer_rule_id` | string (UUID) | Yes      | Unique identifier of the customer compliance rule to update. |

### Request Body

| Field          | Type   | Required | Description                                               |
| -------------- | ------ | -------- | --------------------------------------------------------- |
| `status`       | string | No\*     | Rule status. Allowed values: `enabled`, `disabled`.       |
| `param_values` | object | No\*     | Rule configuration values used during carrier evaluation. |

\* At least one of `status` or `param_values` must be provided.

### Observed by GenLogs Validation

When updating the Observed by GenLogs rule, `param_values` is strictly validated before the update is processed.

Validation applies only to this external API endpoint. Internal GenLogs UI/API update flows are not affected.

#### `date_interval`

Must be a supported interval value:

* `1_day`
* `7_days`
* `14_days`
* `1_month`
* `3_months`
* `6_months`
* `12_months`
* `18_months`
* `2_years`
* `3_years`
* `4_plus_years`

#### `decision_matrix`

Must follow this structure:

{% code expandable="true" %}

```json
{"false": "<value>","true": "<value>"}
```

{% endcode %}

Rules:

* Only allowed keys: `false`, `true`
* `false` must be `review` or `fail`
* `true` must be `pass`
* No extra keys are allowed

Valid combinations:

| `false`  | `true` |
| -------- | ------ |
| `review` | `pass` |
| `fail`   | `pass` |

#### `fail_message`

Must be a strict boolean (`true` or `false`).

Rejected examples:

* `"false"` (string)
* `0` (number)

#### `pass_message`

Must be a strict boolean (`true` or `false`).

Rejected examples:

* `"true"` (string)
* `1` (number)

### Request Examples

#### Update status only

{% code overflow="wrap" %}

```bash
curl --location --request PATCH 'https://api.genlogs.io/customer-compliance-rules/{id}' \
--header 'access-token: <your-api-token>' \
--header 'x-api-key: <your-x-api-key>' \
--header 'Content-Type: application/json' \
--data '{
  "status": "enabled"
}'
```

{% endcode %}

#### Update Observed by GenLogs rule — review when not observed

{% code overflow="wrap" %}

```bash
curl --location --request PATCH 'https://api.genlogs.io/customer-compliance-rules/{id}' \
--header 'access-token: <your-api-token>' \
--header 'x-api-key: <your-x-api-key>' \
--header 'Content-Type: application/json' \
--data '{
  "status": "enabled",
  "param_values": {
    "date_interval": "1_month",
    "decision_matrix": {
      "false": "review",
      "true": "pass"
    },
    "fail_message": false,
    "pass_message": true
  }
}'
```

{% endcode %}

### Responses

| Status                      | Description                                                               |
| --------------------------- | ------------------------------------------------------------------------- |
| `200 OK`                    | Customer compliance rule updated successfully.                            |
| `400 Bad Request`           | Invalid request body, missing required fields, or invalid `param_values`. |
| `401 Unauthorized`          | Authentication credentials are missing or invalid.                        |
| `403 Forbidden`             | User does not have the required permission.                               |
| `404 Not Found`             | Customer compliance rule does not exist.                                  |
| `500 Internal Server Error` | Server error while processing the request.                                |

### Response Body

#### `200 OK`

{% code overflow="wrap" %}

```json
{
  "message": "Success! The customer rule has been updated.",
  "status_code": 200
}
```

{% endcode %}

#### `400 Bad Request`

Returned when:

* Neither `status` nor `param_values` is provided
* `param_values` contains invalid Observed by GenLogs values

Missing update fields

{% code overflow="wrap" %}

```json
{
    "message": "At least status or param_values must be provided for update"
}
```

{% endcode %}

Invalid `date_interval`

{% code expandable="true" %}

```json
{
    "detail": "Invalid param_values for Observed by GenLogs: param_values.date_interval: Value error, Unsupported date interval: last_week"
}
```

{% endcode %}

Invalid `decision_matrix` value

{% code expandable="true" %}

```json
{
    "detail": "Invalid param_values for Observed by GenLogs: param_values.decision_matrix.false: Input should be 'review' or 'fail'"
}
```

{% endcode %}

Invalid `decision_matrix` combination

{% code expandable="true" %}

```json
{
    "detail": "Invalid param_values for Observed by GenLogs: param_values.decision_matrix.true: Input should be 'pass'"
}
```

{% endcode %}

Non-boolean message flags

{% code expandable="true" %}

```json
{
    "detail": "Invalid param_values for Observed by GenLogs: param_values.fail_message: Input should be a valid boolean"
}
```

{% endcode %}

#### `401 Unauthorized`

{% code expandable="true" %}

```json
{
    "detail": {"message": "Token is missing","subcode": "TOKEN_MISSING"}
}
```

{% endcode %}

#### `403 Forbidden`

{% code expandable="true" %}

```json
{
    "detail": "User does not have the required permissions to access this resource"
}
```

{% endcode %}

#### `404 Not Found`

{% code expandable="true" %}

```json
{
    "message": "Customer rule id: {id} not found"
}
```

{% endcode %}

## Update customer compliance rule

> Updates the status and/or parameter values of an existing customer compliance rule. At least one of \`status\` or \`param\_values\` must be provided. The authenticated company must have vetting access permissions.<br>

```json
{"openapi":"3.0.3","info":{"title":"Customer Compliance Rules API","version":"1.0.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"Access-Token":[],"X-Api-Key":[]}],"components":{"securitySchemes":{"Access-Token":{"type":"apiKey","in":"header","name":"Access-Token","description":"JWT provided directly in the Access-Token header.\n"}}},"paths":{"/customer-compliance-rules/{customer_rule_id}":{"patch":{"summary":"Update customer compliance rule","description":"Updates the status and/or parameter values of an existing customer compliance rule. At least one of `status` or `param_values` must be provided. The authenticated company must have vetting access permissions.\n","tags":["Compliance Rules"],"parameters":[{"name":"customer_rule_id","in":"path","required":true,"description":"Unique identifier of the customer compliance rule.","schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","description":"Updated vetting status of the rule.","enum":["enabled","disabled"]},"param_values":{"type":"object","description":"Dynamic parameter values used during carrier evaluation. For the Observed by GenLogs rule, `date_interval` must be a supported interval, `decision_matrix` may only contain `false` and `true` keys, `false` must be `review` or `fail`, and `true` must be `pass`. `fail_message` and `pass_message` must be booleans.\n","additionalProperties":{"oneOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"object"}]}}},"anyOf":[{"required":["status"]},{"required":["param_values"]}]}}}},"responses":{"200":{"description":"Customer compliance rule updated successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"status_code":{"type":"string"},"message":{"type":"string"}}}}}},"400":{"description":"Bad Request – Invalid input, missing required fields, or invalid external rule param_values.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"401":{"description":"Unauthorized – Invalid or missing Access-Token.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"object"}}}}}},"403":{"description":"Forbidden – Company user does not have vetting access permission.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"404":{"description":"Not Found – Customer compliance rule does not exist.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string"}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"type":"string"}}}}}}}}}
```


# Carrier Vetting Rules

Get list of active vetting rules and their configurations

### **Authentication**

* Include your **`Access-Token`** and **`x-api-key`** in the header of your requests.

### Permissions

The `external-api-compliance-rules` permission is required to access this endpoint.

### **Endpoint**

* **URL:**  `https://api.genlogs.io/customer-compliance-rules`
* **Method:** GET

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.&#x20;

### Request Example:

```bash
curl --location 'https://api.genlogs.io/customer-compliance-rules' \
--header 'access-token: <your-api-token>' \
--header 'x-api-key: <your-x-api-key>' \
```

### **Response:**

* **200 OK:** A JSON object containing the list of carrier rules under the authenticated customer.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been set to your user.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

200 OK

```json
{
    "rules": [
        {
            "id": "18ff81b0-acdd-4a9c-a025-b87b1ee201b0",
            "rule_name": "Observed by GenLogs",
            "status": "enabled",
            "param_values": {
                "date_interval": "2_years",
                "decision_matrix": {
                    "false": "review",
                    "true": "pass"
                },
                "fail_message": false,
                "pass_message": true
            }
        }
    ]
}
```

401 Forbidden

```json
{
  "detail": {
    "message": "Token is missing",
    "subcode": "TOKEN_MISSING"
  }
}
```

403 Forbidden

```json
{
    "detail": "User does not have the required permissions to access this resource"
}
```

## Retrieve customer compliance rules

> Returns all compliance rules configured for the authenticated customer. Only rules belonging to the customer associated with the Access-Token are returned. Requires the external-api-compliance-rules permission.<br>

```json
{"openapi":"3.0.3","info":{"title":"Customer Compliance Rules API","version":"1.0.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"Access-Token":[],"X-Api-Key":[]}],"components":{"securitySchemes":{"Access-Token":{"type":"apiKey","in":"header","name":"Access-Token","description":"JWT provided directly in the Access-Token header. No \"Bearer\" prefix.\n"}}},"paths":{"/customer-compliance-rules":{"get":{"summary":"Retrieve customer compliance rules","description":"Returns all compliance rules configured for the authenticated customer. Only rules belonging to the customer associated with the Access-Token are returned. Requires the external-api-compliance-rules permission.\n","tags":["Compliance Rules"],"responses":{"200":{"description":"Compliance rules retrieved successfully.","content":{"application/json":{"schema":{"type":"object","properties":{"rules":{"type":"array","description":"List of compliance rules configured for the customer.","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier of the customer compliance rule."},"rule_name":{"type":"string","description":"Human-readable name of the compliance rule."},"status":{"type":"string","description":"Current status of the rule.","enum":["enabled","disabled"]},"param_values":{"type":"object","description":"Dynamic parameter values used during carrier evaluation.","additionalProperties":{"oneOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"object"}]}}}}}}}}}},"401":{"description":"Unauthorized – Invalid or missing Access-Token.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"object","properties":{"message":{"type":"string"},"subcode":{"type":"string"}}}}}}}},"403":{"description":"Forbidden – User does not have the required permission.","content":{"application/json":{"schema":{"type":"object","properties":{"detail":{"type":"string"}}}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"type":"string"}}}}}}}}}
```


# Shipper Lanes

The shipper lanes recommendation endpoint allows users to retrieve a list of facilities that ship from the specified origin location to the specified destination location within a given distance radius.  The shippers\_in\_origin returned array is the primary fields of interest. shippers\_in\_destination is merely a list of facilities in the specified destination area.

### **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-lanes` permission

### **Endpoint**

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

### **Query Parameters**

* **origin\_city** (string, required): Name of the city of the origin location.
* **origin\_state** (string, required): Name of the state of the origin location.
* **destination\_city** (string, required): Name of the city of the destination location.
* **destination\_state** (string, required): Name of the state of the destination location.
* **origin\_radius** (number, required): The radius (miles) around the origin city within which to search for shipper lanes.
* **destination\_radius** (number, required): The radius (miles) around the destination city within which to search for shipper lanes.
* **lot\_size\_category** (string, optional) Case-sensitive value to filter results.
  * X-Small: Up to 10,000 sq ft
  * Small: 10,001 to 75,000 sq ft
  * Medium: 75,001 to 250,000 sq ft
  * Large: 250,001 to 1,000,000 sq ft
  * X-Large: Over 1,000,000 sq ft

### **Response**

* **200 OK**: Successfully retrieved the list of shipper lanes within the specified radius.
* **400 Bad Request**: If required parameters are missing or invalid.
* **401 Unauthorized**: If the `Access-Token` is missing or invalid.
* **500 Internal Server Error**: If an error occurs on the server while processing the request.

### **Response Body**

* **shippers\_in\_origin** (array of `Shipper` objects): List of shippers that have a lane to the destination.&#x20;
  * **contact\_phone** (nullable string): Phone number of the shipper's contact person.
  * **contact\_url** (nullable string): URL for the shipper's contact page or website.
  * **facility\_name** (string): Name of the shipper's facility.
  * **formatted\_address** (string): Full address of the shipper's facility.
  * **id** (string): Unique identifier for the shipper.
  * **lat** (number): Latitude of the shipper's facility.
  * **lon** (number): Longitude of the shipper's facility.
  * **operating\_hours** (nullable string): Operating hours of the shipper's facility.
  * **place\_category** (string): Category or type of place (Distribution Center or Manufacturing Plant).
  * **place\_desc** (String): Description of the facility
  * **equipment\_pairings** (List): Equipment types paired with this facility based on observed carrier activity.
* **shippers\_in\_destination** (array of `Shipper` objects): List of shippers located at the destination.
  * **contact\_phone** (nullable string): Phone number of the shipper's contact person.
  * **contact\_url** (nullable string): URL for the shipper's contact page or website.
  * **facility\_name** (string): Name of the shipper's facility.
  * **formatted\_address** (string): Full address of the shipper's facility.
  * **id** (string): Unique identifier for the shipper.
  * **lat** (number): Latitude of the shipper's facility.
  * **lon** (number): Longitude of the shipper's facility.
  * **operating\_hours** (nullable string): Operating hours of the shipper's facility.
  * **place\_category** (string): Category or type of place (Distribution Center or Manufacturing Plant).
  * **place\_desc** (String): Description of the facility
  * **equipment\_pairings** (List): Equipment types paired with this facility based on observed carrier activity.

### Request Example:

```sh
curl -X GET 'https://api.genlogs.io/shipper/lanes?name=coca+cola&radius=50&origin_city=Tennessee+City&origin_state=Tennessee&destination_city=Taswell&destination_state=Indiana&origin_radius=50&destination_radius=50' \
-H 'Access-Token: {access_token}' \
-H 'x-api-key: {your_api_key}'
```

## GET /shipper/lanes

> Get shipper lanes based on coordinates and radius

```json
{"openapi":"3.0.2","info":{"title":"Shipper API","version":"1.0.0"},"servers":[{"url":"https://api.genlogs.io"}],"paths":{"/shipper/lanes":{"get":{"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"},{"in":"query","name":"testing_new_param","required":true,"schema":{"type":"number"},"description":"Testing new param"},{"in":"query","name":"origin_lat","required":true,"schema":{"type":"number"},"description":"Latitude of the origin location"},{"in":"query","name":"origin_lon","required":true,"schema":{"type":"number"},"description":"Longitude of the origin location"},{"in":"query","name":"destination_lat","required":true,"schema":{"type":"number"},"description":"Latitude of the destination location"},{"in":"query","name":"destination_lon","required":true,"schema":{"type":"number"},"description":"Longitude of the destination location"},{"in":"query","name":"origin_radius","required":true,"schema":{"type":"number"},"description":"Radius to search around the origin"},{"in":"query","name":"destination_radius","required":true,"schema":{"type":"number"},"description":"Radius to search around the destination"}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShipperLaneResponse"}}},"description":"List of shipper lanes"}},"summary":"Get shipper lanes based on coordinates and radius"}}},"components":{"schemas":{"ShipperLaneResponse":{"properties":{"shippers_in_destination":{"items":{"$ref":"#/components/schemas/Shipper"},"type":"array"},"shippers_in_origin":{"items":{"$ref":"#/components/schemas/Shipper"},"type":"array"}},"required":["shippers_in_destination","shippers_in_origin"],"type":"object"},"Shipper":{"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 shipper 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"}}},"required":["facility_name","formatted_address","id","lat","lon","place_category"],"type":"object"}}}}
```


# 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"]}}}}
```


# Facility Network Map

Returns the GeoJSON network map associated with the provided facility\_id, the map provided has the same information used to render Shipper Network map in Truck Intelligence Portal (example below)

<figure><img src="https://2315646207-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTWLd9L6wPqgOLglGkVHP%2Fuploads%2F2nAA9mVJMWy5VE4wZAkQ%2FScreenshot%202025-11-12%20at%2010.19.46%E2%80%AFAM.png?alt=media&amp;token=1af70f24-ecd5-41ee-93fc-89d208e392a4" alt=""><figcaption></figcaption></figure>

### **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-network-map` permission

### **Endpoint**

* **URL**: `https://api.genlogs.io/facility/<facility_id>/network-map`
* **Method**: `GET`

### **Response**

* **200 OK**: Returns the facility network map in GeoJSON format. The payload is normalized as a FeatureCollection.
* **400 Bad Request**: If required parameters are missing or invalid.
* **401 Unauthorized**: If the `Access-Token` or `x-api-key` is missing or invalid.
* **403 Forbidden**: If the user is not allowed to access this endpoint.
* **500 Internal Server Error**: If an error occurs on the server while processing the request.

### **Response Body**

When the request succeeds, the endpoint returns a GeoJSON `FeatureCollection` whose structure follows `FacilityNetworkMapSchema`:

* `type`: Always `FeatureCollection`.
* `features`: Array of GeoJSON `Feature` objects.
* Each feature has:
  * `geometry`: standard GeoJSON geometry (point, line, polygon) with coordinates relative to the facility.
  * `properties`: metadata about the lane (analysis window, history window, etc.).

### **Request example**

```
curl --location 'https://api.genlogs.io/facility/0x4Y4CTmYr6kauPugLT9k4zg/network-map' \
--header 'Content-Type: application/json' \
--header 'access-token: <access-token>' \
--header 'x-api-key: <x-api-key>'
```

## Retrieve the GeoJSON network map for a facility

> Returns the GeoJSON network map associated with the specified facility.

```json
{"openapi":"3.0.2","info":{"title":"Shipper API - Facility Network Map","version":"1.0.0"},"tags":[{"name":"Facilities","description":"Returns the facility network map in GeoJSON format"}],"servers":[{"url":"https://api.genlogs.io"}],"paths":{"/facility/{facility_id}/network-map":{"get":{"summary":"Retrieve the GeoJSON network map for a facility","description":"Returns the GeoJSON network map associated with the specified facility.","operationId":"getFacilityNetworkMap","tags":["Facilities"],"parameters":[{"name":"facility_id","in":"path","required":true,"schema":{"type":"string"},"description":"Trimble identifier for the facility."}],"responses":{"200":{"description":"Facility GeoJSON network map (FeatureCollection)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FacilityNetworkMap"}}}},"401":{"description":"Missing or invalid token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthError"}}}},"403":{"description":"Token expired or user lacks the required role.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthError"}}}},"500":{"description":"Unexpected error while fetching or parsing GeoJSON.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]}}}}}}}},"components":{"schemas":{"FacilityNetworkMap":{"type":"object","required":["type","features"],"properties":{"type":{"type":"string"},"features":{"type":"array","items":{"$ref":"#/components/schemas/FacilityNetworkFeature"}}}},"FacilityNetworkFeature":{"type":"object","required":["type","geometry","properties"],"properties":{"type":{"type":"string"},"geometry":{"$ref":"#/components/schemas/GeoJSONGeometry"},"properties":{"type":"object","additionalProperties":true,"description":"Arbitrary metadata associated with the feature."}}},"GeoJSONGeometry":{"type":"object","required":["type","coordinates"],"properties":{"type":{"type":"string","enum":["Point","LineString","Polygon","MultiPoint","MultiLineString","MultiPolygon"]},"coordinates":{"type":"array","items":{},"description":"GeoJSON coordinate array whose structure depends on geometry type."}}},"AuthError":{"type":"object","properties":{"message":{"type":"string"},"subcode":{"type":"integer","description":"Optional subcode with additional error context."}}}}}}
```


# Alert Run Summary

*The Run Alerts Summary endpoint allows customers to trigger their all their configured alerts. This summary list all alerts configured and send via email the results based on the asset detections matches*

> **Note**: This endpoint does **not** require any request body parameters, as it automatically uses the `customer_id` from the authenticated token.

### 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 `admin` or`run-summary-alert`  permission

### Endpoint

* **URL**: `https://api.genlogs.io/alerts/run`
* **Method**: `POST`

### Response Codes

* `200 OK`: Alert execution request successfully created.
* `400 Bad Request`: An error occurred while processing the alerts.
* `401 Unauthorized`: Authentication credentials are missing or incorrect.
* `403 Forbidden`: The user does not have permission to run alerts.
* `500 Internal Server Error`: An issue occurred on the server.

### Response Body

```json
{
  "message": "Alert execution request was created. You will receive an email soon with the result"
}
```

### Request Example

Using `curl`:

```bash
curl -X POST 'https://api.genlogs.io/alerts/run' \
-H 'Access-Token: {access_token}' \
-H 'x-api-key: {your_api_key}' \
-H 'Content-Type: application/json'
```


# Mismatch Alerts

Mismatch alerts proactively notify customers when their assets are being hauled by carriers outside of an approved list.&#x20;


# Create Mismatch Alerts

Creates trailer mismatch observation alerts for the authenticated customer from standalone USDOT numbers, standalone MC numbers, and paired MC/USDOT records.

### **Authentication**

* Include your **`Access-Token`** and **`x-api-key`** in the header of your requests.

### Permissions

The `external-api-mismatch-observations` or `admin` permission is required to access this endpoint.

### **Endpoint**

* **URL:** `https://api.genlogs.io/mismatch-observations`
* **Method:** POST

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.

### Request body:

* `usdots` (list of USDOTs, optional or required when `mcs` is not provided): list of the requested USDOT numbers to create a mismatch alert
* `mcs` (list of MCs, optional or required when `usdots` is not provided): list of the requested MC numbers to create a mismatch alert
* `pairs` (list of objects, optional): Paired MC/USDOT records. Each object creates one combined mismatch alert with both values.
  * Each `pairs` object must include:

    <pre class="language-json" data-expandable="true"><code class="lang-json"><strong>{"mc": "7894","usdot": "9637"}
    </strong></code></pre>
* `alert_name` (srt, optional): related name of the alert(s) for client use.
* `logos` (list of Logos, optional): list of the optional logos names to create a mismatch alert

### Request Example:

```bash
curl --location 'https://api.genlogs.io/mismatch-observations' \
--header 'access-token: <your-api-token>' \
--header 'x-api-key: <your-x-api-key>' \
--data-raw '{
  "usdots": ["10000", "200000", "300000"],
  "mcs": ["4000", "5000"],
  "pairs": [
    {
      "mc": "7894",
      "usdot": "9637"
    }
  ],
  "alert_name": "Custom mismatch trailer alert",
  "logos": ["logo_name1", "logo_name2"]
}'
```

### **Response:**

* `201 Created`: Returns a confirmation message and the count of created alerts.
* `400 Bad Request`: Missing or invalid request parameters.
* `401 Unauthorized`: Missing or invalid `Access-Token`.
* `403 Forbidden`: User does not have the required permission.
* `500 Internal Server Error`: Server error while processing the request.

### **Response Body:**

201 Created

```json
{
    "message": "Mismatch alerts created successfully.",
    "data": {
        "created": 4
    }
}
```

400 Bad Request

```json
{
  "detail": "At least one USDOT, MC, or pair must be provided."
}
```

401 Forbidden

```json
{
  "detail": {
    "message": "Token is missing",
    "subcode": "TOKEN_MISSING"
  }
}
```

403 Forbidden

```json
{
    "detail": "User does not have the required permissions to access this resource"
}
```

## Create mismatch observation alerts

> Creates one alert row per standalone USDOT or MC value, and one combined row per item in \`pairs\`. At least one of \`usdots\`, \`mcs\`, or \`pairs\` must be non-empty. \`alert\_name\` is optional; when omitted or blank, stored as null. \`logos\` is optional and, when present, is normalized to lowercase, stored in \`logos\`, and used by mismatch detection. Logo matching remains case-insensitive. Unknown JSON properties are rejected.<br>

```json
{"openapi":"3.0.3","info":{"title":"Mismatch observation alerts (external API)","version":"1.4.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"Access-Token":[],"X-Api-Key":[]}],"components":{"securitySchemes":{"Access-Token":{"type":"apiKey","in":"header","name":"Access-Token"}},"schemas":{"ExternalMismatchObservationsRequest":{"type":"object","additionalProperties":false,"properties":{"usdots":{"type":"array","items":{"type":"string"},"description":"USDOT numbers (strings). Each non-empty entry creates one alert.","default":[]},"mcs":{"type":"array","items":{"type":"string"},"description":"MC numbers (strings). Each non-empty entry creates one alert.","default":[]},"pairs":{"type":"array","items":{"$ref":"#/components/schemas/MismatchObservationPairRequest"},"description":"Paired MC/USDOT identifiers. Each item creates one combined alert row with both MC and USDOT in the stored criteria.\n","default":[]},"logos":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Optional trailer logos list. Each value must be a non-empty string. Values are trimmed, deduplicated, and stored in lowercase format. Matching against the logos catalog.\n"},"alert_name":{"type":"string","nullable":true,"description":"Optional display name; omitted or whitespace-only is stored as null."}}},"MismatchObservationPairRequest":{"type":"object","additionalProperties":false,"required":["mc","usdot"],"properties":{"mc":{"type":"string","minLength":1,"description":"MC number for the combined alert row."},"usdot":{"type":"string","minLength":1,"description":"USDOT number for the combined alert row."}}}}},"paths":{"/mismatch-observations":{"post":{"summary":"Create mismatch observation alerts","description":"Creates one alert row per standalone USDOT or MC value, and one combined row per item in `pairs`. At least one of `usdots`, `mcs`, or `pairs` must be non-empty. `alert_name` is optional; when omitted or blank, stored as null. `logos` is optional and, when present, is normalized to lowercase, stored in `logos`, and used by mismatch detection. Logo matching remains case-insensitive. Unknown JSON properties are rejected.\n","tags":["Mismatch alerts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExternalMismatchObservationsRequest"}}}},"responses":{"201":{"description":"Mismatch alerts created successfully.","content":{"application/json":{"schema":{"type":"object","required":["message","data"],"properties":{"message":{"type":"string"},"data":{"type":"object","properties":{"created":{"type":"integer","description":"Number of alerts inserted."}}}}}}}},"400":{"description":"Bad request – validation error or empty usdots/mcs/pairs."},"401":{"description":"Unauthorized – Invalid or missing Access-Token."},"403":{"description":"Forbidden – missing permission."},"500":{"description":"Internal Server Error."}}}}}}
```


# Get Mismatch Alerts

Lists trailer mismatch observation alerts for the authenticated customer.

### **Authentication**

* Include your **`Access-Token`** and **`x-api-key`** in the header of your requests.

### Permissions

The `external-api-mismatch-observations` or `admin` permission is required to access this endpoint.

### **Endpoint**

* **URL:** `https://api.genlogs.io/mismatch-observations`
* **Method:** GET

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.

### Request Example:

```bash
curl --location 'https://api.genlogs.io/mismatch-observations?page=1&page_size=5' \
--header 'access-token: <your-api-token>' \
--header 'x-api-key: <your-x-api-key>'
```

### **Response:**

* **200 OK:** A JSON object containing the list of paginated trailer mismatch alerts.
* **400 Bad Request:** If one of the provided parameters is incorrect.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been set to your user.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

200 OK

* `mismatch_observations` (**list**): list of trailer mismatch observations including related information.
  * `id` (**str**, UUID): unique identifier of the alert.
  * `name` (**str**, optional, nullable): alert display name. If not provided when the alert is created, it is set to `null`.
  * `usdot` (**str**, nullable): USDOT value associated with the mismatch observation. `null` when not applicable.
  * `mc` (**str**, nullable): MC value associated with the mismatch observation. `null` when not applicable.
  * `logos` (list): list of logos to filter in the mismatch observations
  * `is_disabled` (bool): indicates whether the mismatch alert is disabled.
  * `created_at` (str, date-time): creation timestamp in ISO-8601 format.
  * `last_run_at` (str, date-time, nullable): last run timestamp in ISO-8601 format.
* `page` (**int**): current page number (1-based).
* `page_size` (**int**): number of items returned per page.
* `total` (**int**): total number of mismatch observations available for the customer.

{% code expandable="true" %}

```json
{
    "mismatch_observations": [
        {
            "id": "b9291b70-2383-4e5d-9f33-ecd5808b96a2",
            "name": null,
            "usdot": null,
            "mc": "300000",
            "logos": [
                "logo_1",
                "logo_2"
            ],
            "is_disabled": false,
            "created_at": "2026-04-07T22:30:02.608190",
            "last_run_at": null
        },
        {
            "id": "3145720d-4c09-440b-89da-616d3b9adb4c",
            "name": "mismatch alert mc 4000",
            "usdot": null,
            "mc": "4000",
            "logos": [],
            "is_disabled": true,
            "created_at": "2026-04-07T22:29:54.563299",
            "last_run_at": null
        }
    ],
    "page": 1,
    "page_size": 2,
    "total": 10
}
```

{% endcode %}

400 Bad Request

```json
{
    "message": "Invalid request parameters: 'page_size'",
    "error_code": "VALIDATION_ERROR"
}
```

401 Forbidden

```json
{
  "detail": {
    "message": "Token is missing",
    "subcode": "TOKEN_MISSING"
  }
}
```

403 Forbidden

```json
{
    "detail": "User does not have the required permissions to access this resource"
}
```

## List mismatch observations

> Returns mismatch observations for the authenticated customer only, ordered from newest to oldest. Paginated; default page size is 50. Returns 200 with an empty \`mismatch\_observations\` array when none exist.<br>

```json
{"openapi":"3.0.3","info":{"title":"Mismatch observation alerts (external API)","version":"1.4.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"Access-Token":[],"X-Api-Key":[]}],"components":{"securitySchemes":{"Access-Token":{"type":"apiKey","in":"header","name":"Access-Token"}},"schemas":{"MismatchObservationsListResponse":{"type":"object","required":["mismatch_observations","page","page_size","total"],"properties":{"mismatch_observations":{"type":"array","items":{"$ref":"#/components/schemas/MismatchObservationItem"}},"page":{"type":"integer","minimum":1,"description":"Current page number."},"page_size":{"type":"integer","minimum":1,"maximum":500,"description":"Page size used for this response."},"total":{"type":"integer","minimum":0,"description":"Total number of observations for this customer (all pages)."}}},"MismatchObservationItem":{"type":"object","required":["id","usdot","mc","is_disabled"],"properties":{"id":{"type":"string","format":"uuid","description":"Alert row identifier."},"alert_name":{"type":"string","nullable":true,"description":"Optional display name; may be null if not set."},"usdot":{"type":"string","nullable":true,"description":"USDOT value from stored criteria."},"mc":{"type":"string","nullable":true,"description":"MC value from stored criteria."},"logos":{"type":"array","items":{"type":"string"},"description":"Trailer logos from `logos`, returned in normalized lowercase format. Empty when not configured.","default":[]},"is_disabled":{"type":"boolean","description":"Whether this mismatch observation alert is disabled."},"created_at":{"type":"string","format":"date-time","nullable":true,"description":"Creation timestamp when available."},"last_run_at":{"type":"string","format":"date-time","nullable":true,"description":"Last run timestamp in ISO-8601 format; null when not run yet."}}}}},"paths":{"/mismatch-observations":{"get":{"summary":"List mismatch observations","description":"Returns mismatch observations for the authenticated customer only, ordered from newest to oldest. Paginated; default page size is 50. Returns 200 with an empty `mismatch_observations` array when none exist.\n","tags":["Mismatch alerts"],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1},"description":"Page number (1-based)."},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":500,"default":50},"description":"Number of items per page (max 500)."}],"responses":{"200":{"description":"Paginated list of mismatch observations for the customer.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MismatchObservationsListResponse"}}}},"401":{"description":"Unauthorized – Invalid or missing Access-Token."},"403":{"description":"Forbidden – missing permission."}}}}}}
```


# Update Mismatch Alerts

Updates trailer mismatch observation alerts for the authenticated customer.

### **Authentication**

* Include your **`Access-Token`** and **`x-api-key`** in the header of your requests.

### Permissions

The `external-api-mismatch-observations` or `admin` permission is required to access this endpoint.

### **Endpoint**

* **URL:** `https://api.genlogs.io/mismatch-observations/{mismatch-alert-id}`
* **Method:** PATCH

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.

### Request body (partial update — at least one field that “counts” is required):

* `usdot` (str, int, optional): New USDOT for this single mismatch alert. `null` clears USDOT in stored criteria. Empty or whitespace-only strings are ignored (not update and not clear).
* `mc` (str, optional): New MC number for this alert; same rules as `usdot` (string/number, `null` clears, blank ignored).
* `logos` (list of logos, optional): updated list of logos to filter in the mismatch observations.  `null` or empty list (`[]`) becomes no custom logos.
* `alert_name` (str, optional): Client-facing label. `null` or blank/whitespace becomes no name (stored as null).
* `is_disabled` (bool, optional): Whether the alert is disabled.

Compared to creation

| Creation (POST)                                                                   | Update (PATCH)                                                                 |
| --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| `usdots` / `mcs` / `pairs` — lists of values; at least one list must be non-empty | `usdot` / `mc` — one string each (this endpoint updates one observation by id) |
| One row per list entry                                                            | Updates the row identified by `{observation_id}`                               |

Other notes

* Unknown JSON keys are rejected.
* If the body is empty, only has ignored blank `usdot`/`mc`, or no applicable fields, the API returns 400 (“no updatable fields”).
* Patching `usdot`/`mc` still runs the same validation as create; invalid combinations can return 400.

### Request Example:

```bash
curl --location 'https://api.genlogs.io/mismatch-observations/{observation-id}' \
--header 'access-token: <your-api-token>' \
--header 'x-api-key: <your-x-api-key>' \
--data-raw '{
    "usdot": "87442",
    "alert_name": "Updated API mismatch ALERT",
    "is_disabled": true,
    "logos": ["logo_1", "logo_2"]
}'
```

### **Response:**

* **200 OK:** A JSON object containing the confirmation values of the updated alert.
* **400 Bad Request:** If one of the request parameters incorrect.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been set to your user.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

200 OK

```json
{
    "id": "{mismatch-alert-id}",
    "alert_name": "Updated API mismatch ALERT",
    "usdot": "87442",
    "mc": null,
    "logos": [
        "logo_1",
        "logo_2"
    ],
    "is_disabled": true,
    "created_at": "2026-04-08T19:11:18.023892",
    "last_run_at": null
}
```

400 Bad Request (e.g. empty object `{}`)

```json
{
    "detail": "At least one field must be provided."
}
```

401 Forbidden

```json
{
  "detail": {
    "message": "Token is missing",
    "subcode": "TOKEN_MISSING"
  }
}
```

403 Forbidden

```json
{
    "detail": "User does not have the required permissions to access this resource"
}
```

## Update a mismatch observation

> Partial update of USDOT (\`usdot\`), MC (\`mc\`), \`logos\`, display name (\`alert\_name\`), and/or \`is\_disabled\`. Send at least one field. Requires permission \`external-api-mismatch-observations\` or admin. Only alerts belonging to the JWT \`customer\_id\` can be updated; otherwise 403. \`logos\` values are normalized to lowercase before persistence and response. Logo matching remains case-insensitive. Returns the full updated observation (same shape as list items).<br>

```json
{"openapi":"3.0.3","info":{"title":"Mismatch observation alerts (external API)","version":"1.4.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"Access-Token":[],"X-Api-Key":[]}],"components":{"securitySchemes":{"Access-Token":{"type":"apiKey","in":"header","name":"Access-Token"}},"schemas":{"MismatchObservationPatchRequest":{"type":"object","additionalProperties":false,"description":"At least one property must be present (after applying ignore rules). Omitted fields are left unchanged. Empty string or whitespace-only `usdot` / `mc` values are ignored (they do not clear the field). JSON `null` for `usdot` / `mc` still clears that side of the criteria when present. USDOT/MC validation matches create rules (numeric after normalization).\n","properties":{"usdot":{"type":"string","nullable":true,"description":"New USDOT value; null clears when paired with MC update rules."},"mc":{"type":"string","nullable":true,"description":"New MC value; null clears when paired with USDOT update rules."},"logos":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Trailer logos list. Values are trimmed, deduplicated, and stored/returned in lowercase format. Matching against the logos catalog.\n"},"alert_name":{"type":"string","nullable":true,"description":"Display name; blank or whitespace-only is stored as null."},"is_disabled":{"type":"boolean","description":"Whether the observation is disabled."}}},"MismatchObservationItem":{"type":"object","required":["id","usdot","mc","is_disabled"],"properties":{"id":{"type":"string","format":"uuid","description":"Alert row identifier."},"alert_name":{"type":"string","nullable":true,"description":"Optional display name; may be null if not set."},"usdot":{"type":"string","nullable":true,"description":"USDOT value from stored criteria."},"mc":{"type":"string","nullable":true,"description":"MC value from stored criteria."},"logos":{"type":"array","items":{"type":"string"},"description":"Trailer logos from `logos`, returned in normalized lowercase format. Empty when not configured.","default":[]},"is_disabled":{"type":"boolean","description":"Whether this mismatch observation alert is disabled."},"created_at":{"type":"string","format":"date-time","nullable":true,"description":"Creation timestamp when available."},"last_run_at":{"type":"string","format":"date-time","nullable":true,"description":"Last run timestamp in ISO-8601 format; null when not run yet."}}}}},"paths":{"/mismatch-observations/{observation_id}":{"patch":{"summary":"Update a mismatch observation","description":"Partial update of USDOT (`usdot`), MC (`mc`), `logos`, display name (`alert_name`), and/or `is_disabled`. Send at least one field. Requires permission `external-api-mismatch-observations` or admin. Only alerts belonging to the JWT `customer_id` can be updated; otherwise 403. `logos` values are normalized to lowercase before persistence and response. Logo matching remains case-insensitive. Returns the full updated observation (same shape as list items).\n","tags":["Mismatch alerts"],"parameters":[{"name":"observation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Mismatch observation (alert) identifier."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MismatchObservationPatchRequest"}}}},"responses":{"200":{"description":"Full updated mismatch observation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MismatchObservationItem"}}}},"400":{"description":"Bad request – empty body, no updatable fields, invalid USDOT/MC, or validation error.\n"},"401":{"description":"Unauthorized – Invalid or missing Access-Token."},"403":{"description":"Forbidden – missing permission, or observation belongs to another customer."},"404":{"description":"Mismatch observation not found or deleted."}}}}}}
```

## The MismatchObservationPatchRequest object

```json
{"openapi":"3.0.3","info":{"title":"Mismatch observation alerts (external API)","version":"1.4.0"},"components":{"schemas":{"MismatchObservationPatchRequest":{"type":"object","additionalProperties":false,"description":"At least one property must be present (after applying ignore rules). Omitted fields are left unchanged. Empty string or whitespace-only `usdot` / `mc` values are ignored (they do not clear the field). JSON `null` for `usdot` / `mc` still clears that side of the criteria when present. USDOT/MC validation matches create rules (numeric after normalization).\n","properties":{"usdot":{"type":"string","nullable":true,"description":"New USDOT value; null clears when paired with MC update rules."},"mc":{"type":"string","nullable":true,"description":"New MC value; null clears when paired with USDOT update rules."},"logos":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Trailer logos list. Values are trimmed, deduplicated, and stored/returned in lowercase format. Matching against the logos catalog.\n"},"alert_name":{"type":"string","nullable":true,"description":"Display name; blank or whitespace-only is stored as null."},"is_disabled":{"type":"boolean","description":"Whether the observation is disabled."}}}}}}
```


# Delete Mismatch Alert

Deletes a trailer mismatch observation alerts for the authenticated customer.

### **Authentication**

* Include your **`Access-Token`** and **`x-api-key`** in the header of your requests.

### Permissions

The `external-api-mismatch-observations` or `admin` permission is required to access this endpoint.

### **Endpoint**

* **URL:** `https://api.genlogs.io/mismatch-observations/{mismatch-alert-id}`
* **Method:** DELETE

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **x-api-key** (string, required): The API key provided by GenLogs.

### Request Example:

```bash
curl --location 'https://api.genlogs.io/mismatch-observations/{observation-id}' \
--header 'access-token: <your-api-token>' \
--header 'x-api-key: <your-x-api-key>'
```

### **Response:**

* **204 No Content:** The confirmation of the mismatch alert has ben successfully deleted.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been set to your user.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

204 No Content

401 Forbidden

```json
{
  "detail": {
    "message": "Token is missing",
    "subcode": "TOKEN_MISSING"
  }
}
```

403 Forbidden

```json
{
    "detail": "User does not have the required permissions to access this resource"
}
```

## Delete a mismatch observation

> Permanently removes the row (timestamp hard delete). This is separate from \`is\_disabled\`, which only pauses processing. After delete, the observation no longer appears in GET list and cannot be PATCHed. Same permission as create/list/update. Returns 404 if the id is unknown, belongs to another customer, or is already deleted. Returns 404 if the id is unknown, belongs to another customer, or is already deleted.<br>

```json
{"openapi":"3.0.3","info":{"title":"Mismatch observation alerts (external API)","version":"1.4.0"},"servers":[{"url":"https://api.genlogs.io"}],"security":[{"Access-Token":[],"X-Api-Key":[]}],"components":{"securitySchemes":{"Access-Token":{"type":"apiKey","in":"header","name":"Access-Token"}}},"paths":{"/mismatch-observations/{observation_id}":{"delete":{"summary":"Delete a mismatch observation","description":"Permanently removes the row (timestamp hard delete). This is separate from `is_disabled`, which only pauses processing. After delete, the observation no longer appears in GET list and cannot be PATCHed. Same permission as create/list/update. Returns 404 if the id is unknown, belongs to another customer, or is already deleted. Returns 404 if the id is unknown, belongs to another customer, or is already deleted.\n","tags":["Mismatch alerts"],"parameters":[{"name":"observation_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Observation deleted successfully (no response body)."},"401":{"description":"Unauthorized – Invalid or missing Access-Token."},"403":{"description":"Forbidden – missing permission."},"404":{"description":"Not found, wrong customer, or already deleted."}}}}}}
```


# Create alert

## **Create Alert**

Create Alert endpoint allows our customers to create alerts that are triggered when one of Genlogs sensors detect a truck that match the alert criteria, sending an email with the detection results.

This endpoint is restricted to authorized users with appropriate permissions.

### 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 `admin` or `create-alert-endpoint`  permission

### Endpoint

* **URL**: `https://api.genlogs.io/alerts`
* **Method**: `POST`

### Request Format

All parameters must be sent as JSON in the request body with `Content-Type: application/json` header.

### Request Body Content

* **email** (string, Required): The email address to the alert results if a match is found
* **cc\_emails** (array of strings, Optional): List of additional email addresses to receive notifications  if a match is found based on alerts criteria
* **alert\_type** (string, Required): Specifies the type of alert to be sent.
  * **normal**: Also called "Daily Alerts", these are triggered once per day in the morning.
  * **hot**: Triggered every 15 minutes.
* **disabled** (boolean, Required): Whether the alert is active or disabled.
* **alert\_name** (string, Required): The name of the alert for identification.
* **usdot\_number** (string, Optional): The USDOT number for alert identification.
* **mc\_number** (string, Optional): The MC number for alert identification.
* **license\_plate** (string, Optional): The license plate number related to the alert.
* **vin** (string, Optional):  Last 6 Digits of the vehicle identification number.
* **cab\_number** (string, Optional): The cab number associated with the vehicle.
* **equipment\_type** (string, Optional): The equipment type for alert identification.
* **trailer\_logo** (string, Optional): The logo displayed on the trailer.
  * The logo displayed on the trailer. See \[[List logos](/alerts/list-logos)]\(<https://api.genlogs.io/logos)endpoint>.
* **trailer\_number** (string, Optional): The trailer number associated with the alert.
* **exact\_match\_trailer\_number** (boolean, Optional): Specifies whether the trailer number search should match exactly or be treated as a “contains” search.
  * **true**: Performs an exact match for the trailer number.
  * **false**: Utilizes a “contains” search for the trailer number.
* **deep\_search** (string, Optional): The deep search criteria associated to the alert
* **exact\_match\_deep\_search** (boolean, Optional): Specifies whether the deep search criteria should match exactly or be treated as a “contains” search.
  * **true**: Performs an exact match for the deep search criteria.
  * **false**: Utilizes a “contains” search for the deep search criteria.
* **notification\_channels** (array of strings, Optional): list of channels to receive notifications `"email"`, `"webhook"`. **Default**: `["email"]` if not specified.

### Response Codes

* **200 OK**: Successfully created the alert.
* **400 Bad Request**: Missing or invalid parameters.
* **401 Unauthorized**: Authentication credentials are missing or incorrect.
* **403 Forbidden**: The user does not have permission to create alerts.
* **500 Internal Server Error**: An issue occurred on the server.

### Response Body:

{% hint style="info" %}
You must save the alert ID in order to use the `Edit Alert` endpoint.
{% endhint %}

* **id** (integer): Unique identifier for the alert.
* **email** (string): The email address associated with the alert.
* **cc\_emails** (array of strings): List of additional email addresses for notifications.
* **alert\_name** (string): The name of the alert.
* **usdot\_number** (string): The USDOT number associated to the alert.
* **mc\_number** (string): The MC number associated to the alert.
* **disabled** (boolean): Indicates whether the alert is active or disabled.
* **alert\_type** (string): Type of alert (`normal`or `hot`)
* **location\_state** (string, nullable): State where the alert is triggered.
* **location\_city** (string, nullable): City where the alert is triggered.
* **license\_plate** (string, nullable): License plate involved in the alert.
* **vin** (string, nullable): Vehicle Identification Number.
* **cab\_number** (string, nullable): Cab number.
* **equipment\_type** (string, nullable): Equipment type.
* **trailer\_logo** (string, nullable): Logo on the trailer.
* **trailer\_number** (string, nullable): Trailer number.
* **exact\_match\_trailer\_number** (boolean): Indicates if the trailer number must match exactly.
* **deep\_search** (string, nullable): Deep search criteria.
* **exact\_match\_deep\_search** (boolean)**:** Indicates if the Deep search criteria must match exactly.
* **notification\_channels** (array of strings): Indicates list of channels to receive notifications

### Request Example

Using `curl`:

```
curl -X POST 'https://api.genlogs.io/alerts' \
-H 'Access-Token: {access_token}' \
-H 'x-api-key: {your_api_key}' \
-H 'Content-Type: application/json' \
-d '{
  "email": "user@example.com",
  "cc_emails": "notification@example.com",
  "alert_type": "normal",
  "disabled": false,
  "alert_name": "New alert",
  "trailer_number": "12345",
  "usdot_number": "",
  "deep_search": "",
  "exact_match_deep_search": false
}'
```

This API ensures secure alert creation while maintaining proper role-based access control.


# Edit Alert

Allows api users to update existing alerts. Alerts can currently be created either from Asset Locator Portal or via [Create alert](/alerts/create-alert) . These alerts are triggered when a scheduled job is triggered and perform the search on the detections based on the alerts criteria. Notifications are sent via email and webhooks

This endpoint is restricted to authorized users with appropriate permissions.

***

### 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 your API user is created with a role that includes either `admin` or `edit-alert-endpoint` permissions.

***

### Endpoint

* **URL**: `https://api.genlogs.io/alerts/{alert_id}`
* **Method**: `PATCH`

***

### Request Parameters

Only the following fields are updatable:

* **alert\_name** (string, Optional): The name of the alert for identification. ​
* **location\_state** (string, Optional): State where the alert is triggered. ​
* **location\_city** (string, Optional): City where the alert is triggered. ​
* **license\_plate** (string, Optional): License plate number related to the alert. ​
* **location\_plate\_state** (string, Optional): State where the license plate is registered. ​
* **usdot\_number** (string, Optional): USDOT number of the vehicle. ​
* **mc\_number** (string, Optional): MC number of the vehicle. ​
* **vin** (string, Optional): Last 6 digits of the VIN. ​
* **cab\_number** (string, Optional): Cab number of the vehicle. ​
* **equipment\_type** (string, Optional): Equipment type of the trailer. ​
* **trailer\_logo** (string, Optional): Logo displayed on the trailer. ​
  * You can see the list of available logos at [this](/alerts/list-logos) endpoint.
* **trailer\_number** (string, Optional): Trailer number associated with the alert. ​
* **exact\_match\_trailer\_number** (boolean, Optional): Whether to do an exact match on trailer number.
* **cc\_emails** (array of strings, Optional): Additional recipients for email notifications. ​
* **alert\_type** (string, Optional): `normal` or `hot`. Defines how often alerts are triggered. ​
* **disabled** (boolean, Optional): Indicates whether the alert is active. ​
* **start\_date** (string (ISO 8601 date-time string), Optional): Alert start date. ​
* **end\_date** (string (ISO 8601 date-time string), Optional): Alert end date. ​
* **deep\_search** (boolean, Optional): Enables deeper asset match scanning. ​
* **notification\_channels** (array of strings, Optional): List of channels to receive notifications.

{% hint style="info" %}

* `start_date` and `end_date` accept ISO 8601 date-time strings with `Z`, timezone offsets, or naive date-time strings.
* Timezone-aware input is normalized to UTC and stored/returned without timezone.
* Invalid date-time strings return `400`.
  {% endhint %}

***

### Response Codes

| Code                        | Meaning                                            |
| --------------------------- | -------------------------------------------------- |
| `200 OK`                    | Successfully updated the alert.                    |
| `400 Bad Request`           | Missing or invalid parameters.                     |
| `401 Unauthorized`          | Authentication credentials are missing or invalid. |
| `403 Forbidden`             | User lacks required permissions.                   |
| `404 Not Found`             | No alert found with the specified ID.              |
| `500 Internal Server Error` | An unexpected server error occurred.               |

## External Patch Alert

> Partially update an existing alert by alert\_id. \`start\_date\` and \`end\_date\` accept ISO 8601 date-time strings with \`Z\`, timezone offsets, or no timezone. Timezone-aware values are normalized to UTC and returned without timezone information.

```json
{"openapi":"3.1.0","info":{"title":"Alert API","version":"0.0.1"},"security":[{"APIKeyHeader":[]}],"components":{"securitySchemes":{"APIKeyHeader":{"type":"apiKey","description":"JWT Access Token required for authentication","in":"header","name":"Access-Token"}},"schemas":{"UpdateAlertSchema":{"properties":{"alert_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Alert Name"},"location_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location State"},"location_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location City"},"license_plate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"License Plate"},"license_plate_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"License Plate State"},"usdot_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Usdot Number"},"chassis_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Chassis Number"},"exact_match_chassis_number":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Exact Match Chassis Number","default":false},"container_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Container Number"},"equipment_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Equipment Type"},"exact_match_container_number":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Exact Match Container Number","default":false},"mc_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mc Number"},"vin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vin"},"cab_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cab Number"},"trailer_logo":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trailer Logo"},"trailer_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trailer Number"},"disabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Disabled"},"cc_emails":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Cc Emails"},"alert_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Alert Type"},"exact_match_trailer_number":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Exact Match Trailer Number"},"start_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"ISO 8601 date-time. Values with `Z` or timezone offsets are normalized to UTC and stored/returned without timezone information.","title":"Start Date"},"end_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"ISO 8601 date-time. Values with `Z` or timezone offsets are normalized to UTC and stored/returned without timezone information.","title":"End Date"},"deep_search":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deep Search"},"notification_channels":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Notification Channels"}},"additionalProperties":false,"type":"object","title":"UpdateAlertSchema","description":"Schema for partial updates of alerts (PATCH operations). All fields are optional - only provided fields will be updated."},"AlertResponseSchema":{"properties":{"alert_name":{"type":"string","title":"Alert Name"},"location_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location State"},"location_city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location City"},"license_plate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"License Plate"},"license_plate_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"License Plate State"},"usdot_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Usdot Number"},"chassis_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Chassis Number"},"exact_match_chassis_number":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Exact Match Chassis Number","default":false},"container_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Container Number"},"equipment_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Equipment Type"},"exact_match_container_number":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Exact Match Container Number","default":false},"mc_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mc Number"},"vin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vin"},"cab_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cab Number"},"trailer_logo":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trailer Logo"},"trailer_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Trailer Number"},"disabled":{"type":"boolean","title":"Disabled","default":false},"cc_emails":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Cc Emails"},"alert_type":{"type":"string","title":"Alert Type","default":"normal"},"exact_match_trailer_number":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Exact Match Trailer Number","default":false},"start_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Returned as a timezone-free UTC date-time string after normalization.","title":"Start Date"},"end_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Returned as a timezone-free UTC date-time string after normalization.","title":"End Date"},"deep_search":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deep Search"},"id":{"type":"integer","title":"Id"},"email":{"type":"string","title":"Email"},"last_updated_timestamp":{"type":"string","format":"date-time","title":"Last Updated Timestamp"},"insert_timestamp":{"type":"string","format":"date-time","title":"Insert Timestamp"},"notification_channels":{"items":{"type":"string"},"type":"array","title":"Notification Channels","default":[]}},"additionalProperties":false,"type":"object","required":["alert_name","id","email","last_updated_timestamp","insert_timestamp"],"title":"AlertResponseSchema","description":"Public API response schema for alerts - extends base with response-specific fields"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/alerts/{alert_id}":{"patch":{"tags":["alerts"],"summary":"External Patch Alert","description":"Partially update an existing alert by alert_id. `start_date` and `end_date` accept ISO 8601 date-time strings with `Z`, timezone offsets, or no timezone. Timezone-aware values are normalized to UTC and returned without timezone information.","operationId":"external_patch_alert_alerts__alert_id__patch","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"integer","title":"Alert Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAlertSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertResponseSchema"}}}},"400":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# List Alerts

Retrieve alerts for the authenticated user or company.

* Default: Returns only alerts owned by the authenticated user
* Company-wide: Users with `external-api-get-all-company-alerts` permission can view all authenticated user company alerts

Results are sorted by creation date (newest first). Returns an empty list with 200 OK if no alerts exist.

## Endpoint

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

## Authentication

Requires Bearer token with one of these permissions:

| Permission                            | Access                  |
| ------------------------------------- | ----------------------- |
| `external-api-get-alerts-endpoint`    | View own alerts         |
| `external-api-get-all-company-alerts` | View all company alerts |

## Headers

| Header        | Type   | Required | Description  |
| ------------- | ------ | -------- | ------------ |
| Authorization | string | Yes      | Bearer token |

## Request Example

{% code title="curl" %}

```bash
curl -X GET "https://api.genlogs.io/alerts" \
  -H "Access-Token: YOUR_ACCESS_TOKEN" \
  -H "x-api-key: YOUR_API_KEY"
```

{% endcode %}

## Response (200 OK)

{% code title="application/json" %}

```json
{
  "alerts": [
    {
      "id": 35054,
      "disabled": false,
      "alert_name": "Trailer Tracking",
      "email": "user@company.com",
      "cc_emails": null,
      "start_date": "2026-01-19T05:00:00",
      "end_date": "2026-01-19T05:00:00",
      "location_state": null,
      "location_city": null,
      "license_plate": null,
      "license_plate_state": null,
      "usdot_number": null,
      "mc_number": null,
      "chassis_number": null,
      "container_number": null,
      "exact_match_chassis_number": false,
      "exact_match_container_number": false,
      "vin": null,
      "cab_number": null,
      "equipment_type": null,
      "trailer_logo": null,
      "trailer_number": null,
      "alert_type": "hot",
      "exact_match_trailer_number": false,
      "deep_search": "fx",
      "exact_match_deep_search": false,
      "notification_channels": ["WEBHOOK", "EMAIL"],
      "create_date": "2026-01-19T13:00:39.177379"
    },
    {
      "id": 34547,
      "disabled": false,
      "alert_name": "Fleet Monitor",
      "email": "user@company.com",
      "cc_emails": null,
      "start_date": "2025-11-01T00:00:00",
      "end_date": "2025-11-01T00:00:00",
      "location_state": null,
      "location_city": null,
      "license_plate": null,
      "license_plate_state": null,
      "usdot_number": null,
      "mc_number": null,
      "chassis_number": null,
      "container_number": null,
      "exact_match_chassis_number": null,
      "exact_match_container_number": null,
      "vin": null,
      "cab_number": null,
      "equipment_type": null,
      "trailer_logo": null,
      "trailer_number": null,
      "alert_type": "normal",
      "exact_match_trailer_number": false,
      "deep_search": "az",
      "exact_match_deep_search": false,
      "notification_channels": ["EMAIL"],
      "create_date": "2026-01-08T22:32:41.609945"
    },
    ...
  ]
}
```

{% endcode %}

## Response Fields

| Field                           | Type     | Description                                  |
| ------------------------------- | -------- | -------------------------------------------- |
| id                              | integer  | Unique alert identifier                      |
| disabled                        | boolean  | Whether the alert is disabled                |
| alert\_name                     | string   | Name of the alert                            |
| email                           | string   | Email of the alert owner                     |
| cc\_emails                      | array    | List of CC email addresses for notifications |
| start\_date                     | datetime | Alert start date (ISO 8601)                  |
| end\_date                       | datetime | Alert end date (ISO 8601)                    |
| location\_state                 | string   | State filter for sightings                   |
| location\_city                  | string   | City filter for sightings                    |
| license\_plate                  | string   | License plate to search                      |
| license\_plate\_state           | string   | State of the license plate                   |
| usdot\_number                   | string   | USDOT number to search                       |
| mc\_number                      | string   | MC number to search                          |
| chassis\_number                 | string   | Chassis number to search                     |
| container\_number               | string   | Container number to search                   |
| exact\_match\_chassis\_number   | boolean  | Require exact match for chassis number       |
| exact\_match\_container\_number | boolean  | Require exact match for container number     |
| vin                             | string   | VIN to search                                |
| cab\_number                     | string   | Cab number to search                         |
| equipment\_type                 | string   | Equipment type to search                     |
| trailer\_logo                   | string   | Trailer logo identifier                      |
| trailer\_number                 | string   | Trailer number to search                     |
| alert\_type                     | string   | Alert type: `hot` or `normal`                |
| exact\_match\_trailer\_number   | boolean  | Require exact match for trailer number       |
| deep\_search                    | string   | Deep search query                            |
| exact\_match\_deep\_search      | boolean  | Require exact match for deep search          |
| notification\_channels          | array    | Notification methods: `EMAIL`, `WEBHOOK`     |
| create\_date                    | datetime | Creation timestamp                           |

## Error Responses

<details>

<summary>Possible error responses</summary>

| Status | Description                             |
| ------ | --------------------------------------- |
| 401    | Unauthorized - Invalid or missing token |
| 403    | Forbidden - Missing required permission |
| 500    | Internal Server Error                   |

</details>


# List logos

Returns a list of the available trailer logos in lowercase when calling the `Create Alert` endpoint.

#### **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

Ensure your API user has a role with `admin` or `create-alert-endpoint` permission

### **Endpoint**

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

#### Request example

{% code expandable="true" %}

```shellscript
curl --location 'https://api.genlogs.io/logos' \
--header 'Access-Token: {access-token}' \
--header 'X-Api_key: {x-api-key}'
```

{% endcode %}

#### Response example

{% code expandable="true" %}

```json
[
    "10 roads express",
    "aaa cooper transportation",
    "aat carriers",
    "abf"
]
```

{% endcode %}


# Webhook Specifications

### Overview

The Genlogs webhooks integration sends notifications when alerts are triggered and matches are found in truck detections. The system operates with a clear separation between webhook endpoints and alert configurations:

* **Webhooks**: Define where notifications are sent (URL and authentication)
* **Alerts**: Define what to search for (license plates, VINs, USDOT numbers, etc.)

Only enabled webhooks (enabled = true) will receive notifications during processing.

### How Webhook Alerts Work

Webhook alerts operate using the same processing system as email alerts:

* Unified Processing: Both webhook and email alerts use identical search algorithms and scheduling
* Same Data Source: Webhooks receive the exact same detection matches that would trigger email notifications
* Parallel Delivery: When alerts find matches, the system simultaneously:
  * Sends email notifications to the configured email addresses
  * Sends webhook payloads to all active webhook endpoints
* Consistent Timing: Webhook notifications are sent at the same time as email alerts during each processing cycle
* Shared Alert Rules: The same alert configurations trigger both email and webhook notifications

### **Current Trigger Methods**:

1. **Manually** from the **Asset Locator UI** using the **“**&#x52;un Alert Summar&#x79;**”** button.
2. **Programmatically** by calling the `/run` [endpoint](/alerts/alert-run-summary) from the API.
3. **Automatically** once per day in the morning via a scheduled background process.

This means if you currently receive email alerts, enabling webhooks will provide you with the same alert data via HTTP requests to your chosen endpoints.

### Key aspects

* **Separate Management**: Webhooks and alerts are managed independently
* **Consolidated Notifications**: Receive one payload with all matches from each one of your alerts
* **Secure & Reliable**: Uses HMAC-SHA512 signature verification and HTTPS-only endpoints
* **Pre-flight Testing**: Test your webhook endpoint before deploying
* **Cron-Driven Processing**: Alerts are processed on a schedule to find new matches since the last run
* **Image URL expiration**: Expiration date to consult the URLs to view the truck images (front, side and rear) is one month
* **Companywide notifications**: Webhooks are called for each of the alerts, regardless of the user that created the alert
* **Multiples webhooks support**: Company can set multiple webhook urls
* **Webhook management**: Customer can create, edit , delete and get list of webhook urls

### Security

* **HMAC-SHA512 Signatures**: All payloads are signed for authenticity verification
* **Unique Secret Keys**: Each webhook has its own secret key
* **HTTPS-only URLs**: Required for all webhook endpoints in production
* **JWT Authentication**: API access protected by JWT tokens
* **Role-Based Access Control**: Requires specific user roles to manage webhooks

### Webhook Payload Format

When one or more alerts find new matches, GenLogs sends a payload with the event type `alert.matches_found`.

#### Payload Structure

{% hint style="info" %}

#### Imputed Fields

Fields **is\_usdot\_imputed**, **is\_cab\_imputed**, **is\_mc\_imputed**, **is\_trailer\_logo\_imputed** and **is\_vin\_imputed** represent whether the corresponding field value was inferred or auto-filled by the system rather than directly observed.

These fields are boolean and help differentiate between raw observations and system-generated estimations.

*\*this feature requires permission access*
{% endhint %}

{% hint style="info" %}

#### OCR Score Fields

Fields **usdot\_number\_ocr\_score**, **mc\_number\_ocr\_score**, **vin\_ocr\_score**, **cab\_number\_ocr\_score**, **trailer\_number\_ocr\_score**, and **trailer\_logo\_ocr\_score** represent the **OCR** reading reliability classification for their associated fields.\
For example, **usdot\_number\_ocr\_score** represents the confidence level for the **usdot\_number** field.

**Possible values are**:

* **High** – The OCR result has a high level of confidence.
* **Medium** – The OCR result has a moderate level of confidence; manual verification may be required.
* **Low** – The OCR result has a low level of confidence; manual review is recommended.
* **N/A** – No OCR score is available for this field.

*\*this feature requires permission access*
{% endhint %}

{% hint style="info" %}

#### Hazmat Indicator Field

**Field:** `is_hazmat`

The `is_hazmat` field indicates whether the carrier is identified as operating hazardous materials (HAZMAT). This value represents the system’s determination based on available carrier data and regulatory signals.

**Possible values:**

* `true` – The carrier is identified as operating hazardous materials.
* `false` – The carrier is not identified as operating hazardous materials.

*\*this feature requires permission access*
{% endhint %}

```json
{
  "event": "alert.matches_found",
  "webhook_id": "123e4567-e89b-12d3-a456-426614174000",
  "customer_id": 123,
  "alert_details": [
    {
      "id": 12345,
      "alert_name": "Stolen Trailer T-123",
      "email": "alerts@company.com",
      "description": "Alert for stolen trailer with specific identifiers",
      "is_active": true,
      "license_plate": "ABC1234",
      "vin": "1HGCM82633A004352",
      "usdot_number": "987654",
      "mc_number": "111111",
      "trailer_number": "T-123",
      "cab_number": "CAB789",
      "trailer_logo": "Some Logo"
    }
  ],
  "matches": [
    {
      "alert_name": "alert name",
      "result_url": "https://app.genlogs.com/search/result/...",
      "front_view_url": "https://api-assetlocator.genlogs.io/search/search_images/...",
      "side_view_url": "https://api-assetlocator.genlogs.io/search/search_images/...",
      "rear_view_url": "https://api-assetlocator.genlogs.io/search/search_images/...",
      "time": "2026-04-25T00:00:00",
      "city": "Houston",
      "state": "TX",
      "road": "I-45",
      "lat_long": "29.7604, -95.3698",
      "license_plate": "ABC1234",
      "vin": "1HGCM82633A004352",
      "usdot": "987654",
      "mc": "111111",
      "cab_number": "CAB789",
      "trailer_logo": "Some Logo",
      "trailer_number": "T-123",
      "deep_search": "Matched text from deep search",
      "detected_logos": [],
      "confidence_score": "High",
      "usdot_number_ocr_score": "High",
      "mc_number_ocr_score": "Medium",
      "vin_ocr_score": "High",
      "cab_number_ocr_score": "Low",
      "trailer_number_ocr_score": "Medium",
      "trailer_logo_ocr_score": "N/A",
      "is_imputed": false,
      "is_dot_imputed": false,
      "is_cab_imputed": true,
      "is_mc_number_imputed": false,
      "is_trailer_logo_imputed": true,
      "is_vin_imputed": false,
      "is_hazmat": false
    }
  ],
  "total_matches": 1,
  "timestamp": "2024-05-21T12:01:00.123456+00:00"
}
```

Json schema specification

{% code expandable="true" %}

```json
{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "required": [
        "alert_details",
        "customer_id",
        "event",
        "matches",
        "timestamp",
        "total_matches",
        "webhook_id"
    ],
    "properties": {
        "alert_details": {
            "type": "array",
            "items": {
                "type": "object",
                "required": [
                    "alert_name",
                    "description",
                    "email",
                    "id",
                    "is_active",
                    "trailer_logo",
                    "trailer_number"
                ],
                "properties": {
                    "alert_name": {
                        "type": "string"
                    },
                    "cab_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "chassis_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "container_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "description": {
                        "type": "string"
                    },
                    "email": {
                        "type": "string",
                        "format": "email"
                    },
                    "equipment_type": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "id": {
                        "type": "integer"
                    },
                    "is_active": {
                        "type": "boolean"
                    },
                    "license_plate": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "mc_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "trailer_logo": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        }
                    },
                    "trailer_number": {
                        "type": "string"
                    },
                    "usdot_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "vin": {
                        "type": [
                            "string",
                            "null"
                        ]
                    }
                },
                "additionalProperties": false
            }
        },
        "customer_id": {
            "type": "integer"
        },
        "event": {
            "type": "string",
            "enum": [
                "alert.matches_found"
            ]
        },
        "matches": {
            "type": "array",
            "items": {
                "type": "object",
                "required": [
                    "alert_name",
                    "city",
                    "detected_logos",
                    "lat_long",
                    "time"
                ],
                "properties": {
                    "alert_name": {
                        "type": "string"
                    },
                    "cab_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "chassis_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "container_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "city": {
                        "type": "string"
                    },
                    "deep_search": {
                        "type": "string"
                    },
                    "detected_logos": {
                        "type": [
                            "array",
                            "null"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "equipment_type": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "front_view_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "anyOf": [
                            {
                                "format": "uri"
                            },
                            {
                                "const": "N/A"
                            }
                        ]
                    },
                    "rear_view_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "anyOf": [
                            {
                                "format": "uri"
                            },
                            {
                                "const": "N/A"
                            }
                        ]
                    },
                    "side_view_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "anyOf": [
                            {
                                "format": "uri"
                            },
                            {
                                "const": "N/A"
                            }
                        ]
                    },
                    "lat_long": {
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d+,\\s?-?\\d+\\.\\d+$"
                    },
                    "license_plate": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "mc": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "result_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "uri"
                    },
                    "road": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "state": {
                        "type": "string",
                        "minLength": 2,
                        "maxLength": 2
                    },
                    "time": {
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}$"
                    },
                    "trailer_logo": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "trailer_number": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "usdot": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "vin": {
                        "type": [
                            "string",
                            "null"
                        ]
                    },
                    "confidence_score": {
                        "type": "string",
                        "enum": [
                            "High",
                            "Medium",
                            "Low"
                        ]
                    },
                    "usdot_number_ocr_score": {
                        "type": "string",
                        "enum": [
                            "High",
                            "Medium",
                            "Low"
                        ]
                    },
                    "mc_number_ocr_score": {
                        "type": "string",
                        "enum": [
                            "High",
                            "Medium",
                            "Low"
                        ]
                    },
                    "vin_ocr_score": {
                        "type": "string",
                        "enum": [
                            "High",
                            "Medium",
                            "Low"
                        ]
                    },
                    "cab_number_ocr_score": {
                        "type": "string",
                        "enum": [
                            "High",
                            "Medium",
                            "Low"
                        ]
                    },
                    "trailer_number_ocr_score": {
                        "type": "string",
                        "enum": [
                            "High",
                            "Medium",
                            "Low"
                        ]
                    },
                    "trailer_logo_ocr_score": {
                        "type": "string",
                        "enum": [
                            "High",
                            "Medium",
                            "Low",
                            "N/A"
                        ]
                    },
                    "is_imputed": {
                        "type": "boolean"
                    },
                    "is_dot_imputed": {
                        "type": "boolean"
                    },
                    "is_cab_imputed": {
                        "type": "boolean"
                    },
                    "is_mc_number_imputed": {
                        "type": "boolean"
                    },
                    "is_trailer_logo_imputed": {
                        "type": "boolean"
                    },
                    "is_vin_imputed": {
                        "type": "boolean"
                    },
                    "is_hazmat": {
                        "type": "boolean"
                    }
                },
                "additionalProperties": false
            }
        },
        "timestamp": {
            "type": "string",
            "format": "date-time"
        },
        "total_matches": {
            "type": "integer",
            "minimum": 0
        },
        "webhook_id": {
            "type": "string",
            "format": "uuid"
        }
    },
    "additionalProperties": false
}
```

{% endcode %}

#### Payload Fields

| Field           | Type    | Description                               |
| --------------- | ------- | ----------------------------------------- |
| `event`         | string  | Always `"alert.matches_found"`            |
| `webhook_id`    | string  | UUID of the webhook configuration         |
| `customer_id`   | integer | Customer ID associated with the alerts    |
| `alert_details` | array   | Details of all alerts that found matches  |
| `matches`       | array   | All detection matches found               |
| `total_matches` | integer | Total number of matches across all alerts |
| `timestamp`     | string  | ISO timestamp when the webhook was sent   |

#### Alert Details Object

| Field            | Type    | Description                      |
| ---------------- | ------- | -------------------------------- |
| `id`             | int     | ID of the alert                  |
| `alert_name`     | string  | Name of the alert                |
| `email`          | string  | Contact email for the alert      |
| `description`    | string  | Alert description                |
| `is_active`      | boolean | Whether the alert is active      |
| `license_plate`  | string  | License plate criteria (if any)  |
| `vin`            | string  | VIN criteria (if any)            |
| `usdot_number`   | string  | USDOT number criteria (if any)   |
| `mc_number`      | string  | MC number criteria (if any)      |
| `trailer_number` | string  | Trailer number criteria (if any) |
| `cab_number`     | string  | Cab number criteria (if any)     |
| `trailer_logo`   | string  | Trailer logo criteria (if any)   |

#### Match Object Fields

| Field                       | Type              | Description                                                                                                                                     |
| --------------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| alert\_name                 | string            | Name of the alert that generated the match.                                                                                                     |
| result\_url                 | string            | URL to the search result in the Genlogs application.                                                                                            |
| front\_view\_url            | string            | URL of the front-view image associated with the match.                                                                                          |
| side\_view\_url             | string            | URL of the side-view image associated with the match.                                                                                           |
| rear\_view\_url             | string            | URL of the rear-view image associated with the match.                                                                                           |
| time                        | string (ISO 8601) | Timestamp when the match was detected.                                                                                                          |
| city                        | string            | City where the match was detected.                                                                                                              |
| state                       | string            | State where the match was detected.                                                                                                             |
| road                        | string            | Road or highway where the match was detected.                                                                                                   |
| lat\_long                   | string            | Latitude and longitude of the detection location.                                                                                               |
| license\_plate              | string            | Detected license plate number.                                                                                                                  |
| vin                         | string            | Detected Vehicle Identification Number (VIN).                                                                                                   |
| usdot                       | string            | Detected USDOT number.                                                                                                                          |
| mc                          | string            | Detected MC number.                                                                                                                             |
| cab\_number                 | string            | Detected cab number.                                                                                                                            |
| trailer\_number             | string            | Detected trailer number.                                                                                                                        |
| trailer\_logo               | string            | Detected trailer logo text or label.                                                                                                            |
| deep\_search                | string            | Text matched through deep search processing.                                                                                                    |
| confidence\_score           | string            | Overall confidence classification for the match, aligned with `/visual-sightings/carrier-observations` values (e.g. `High`, `Medium`, `Low`).   |
| usdot\_number\_ocr\_score   | string            | OCR confidence score for the detected USDOT number (`High`, `Medium`, `Low`, `N/A`). *Requires permission access.*                              |
| mc\_number\_ocr\_score      | string            | OCR confidence score for the detected MC number (`High`, `Medium`, `Low`, `N/A`). *Requires permission access.*                                 |
| vin\_ocr\_score             | string            | OCR confidence score for the detected VIN (`High`, `Medium`, `Low`, `N/A`). *Requires permission access.*                                       |
| cab\_number\_ocr\_score     | string            | OCR confidence score for the detected cab number (`High`, `Medium`, `Low`, `N/A`). *Requires permission access.*                                |
| trailer\_number\_ocr\_score | string            | OCR confidence score for the detected trailer number (`High`, `Medium`, `Low`, `N/A`). *Requires permission access.*                            |
| trailer\_logo\_ocr\_score   | string            | OCR confidence score for the detected trailer logo (`High`, `Medium`, `Low`, `N/A`). *Requires permission access.*                              |
| is\_imputed                 | boolean           | Indicates whether any field in the match was inferred or auto-filled by the system rather than directly observed. *Requires permission access.* |
| is\_dot\_imputed            | boolean           | Indicates whether the USDOT number value was imputed by the system. *Requires permission access.*                                               |
| is\_cab\_imputed            | boolean           | Indicates whether the cab number value was imputed by the system. *Requires permission access.*                                                 |
| is\_mc\_number\_imputed     | boolean           | Indicates whether the MC number value was imputed by the system. *Requires permission access.*                                                  |
| is\_trailer\_logo\_imputed  | boolean           | Indicates whether the trailer logo value was imputed by the system. *Requires permission access.*                                               |
| is\_vin\_imputed            | boolean           | Indicates whether the VIN value was imputed by the system. *Requires permission access.*                                                        |
| hazmat                      | boolean \| string | Hazmat detection result as stored by the detection system (boolean or label).                                                                   |
| is\_hazmat                  | boolean           | Normalized indicator specifying whether the detected carrier is classified as hazmat.                                                           |

### Signature Verification

GenLogs signs all webhook payloads with an HMAC-SHA512 hash. Verify this signature to ensure payload authenticity. The signature is provided in the `X-GenLogs-Signature` HTTP header.

#### Python Example

```python
import hmac
import hashlib
import json

def verify_signature(payload_body: bytes, signature_header: str, secret: str) -> bool:
    """Verifies the HMAC-SHA521 signature of a webhook payload."""
    if not signature_header:
        return False
    
    hash_object = hmac.new(
        secret.encode('utf-8'),
        msg=payload_body,
        digestmod=hashlib.sha521
    )
    expected_signature = "sha512=" + hash_object.hexdigest()
    
    return hmac.compare_digest(expected_signature, signature_header)

# Usage example in your webhook handler
# webhook_secret = "your-webhook-secret-key"
# signature = request.headers.get('X-GenLogs-Signature')
# is_valid = verify_signature(request.data, signature, webhook_secret)
```

### HTTP Headers

GenLogs includes the following headers with each webhook request:

| Header                | Description                              |
| --------------------- | ---------------------------------------- |
| `Content-Type`        | Always `application/json`                |
| `User-Agent`          | `GenLogs-Webhook/1.0`                    |
| `X-GenLogs-Signature` | HMAC-SHA512 signature for verification   |
| `X-GenLogs-Event`     | Event type (e.g., `alert.matches_found`) |
| `X-GenLogs-Timestamp` | Unix timestamp when the webhook was sent |

### Error Responses

#### 400 Bad Request (WebhookValidationError)

Occurs when request data is invalid (e.g., webhook URL already in use):

```json
{
  "message": "Webhook URL already registered for this customer",
  "error_type": "WebhookValidationError",
  "error_code": "WEBHOOK_VALIDATION_ERROR",
  "details": {
    "field": "webhook_url",
    "webhook_url": "https://your-api.example.com/webhooks/genlogs-alerts"
  }
}
```

#### 404 Not Found (WebhookNotFoundError)

Occurs when trying to update a non-existent webhook:

```json
{
  "message": "Webhook settings 123e4567-e89b-12d3-a456-426614174000 not found",
  "error_type": "WebhookNotFoundError",
  "error_code": "WEBHOOK_NOT_FOUND"
}
```

#### 403 Forbidden (PermissionError)

Occurs when the JWT token lacks required roles:

```json
{
  "detail": "User lacks required roles: ['admin', 'create-alert-webhook-endpoint']"
}
```


# Create Alert Webhook

## Create Webhook

Configure a webhook to receive notifications when any of your active alerts detect a match. Webhooks and alerts are managed separately (see [Alert Webhooks](https://docs.genlogs.io/asset-locator/alert-webhooks)). Once you have registered your webhook, all existing and new alerts from your organization will be sent to your webhook URL.

### Authentication

Include the following headers in your requests:

```
Access-Token: <your-access-token>
```

### Permissions

Ensure your API user has a role with `admin` or `create-alert-webhook-endpoint` permission.

### Endpoint

* **URL**: `https://api.genlogs.io/alerts/webhook`
* **Method**: `POST`

### Request Body

| Field         | Type   | Required | Description                                                         |
| ------------- | ------ | -------- | ------------------------------------------------------------------- |
| `webhook_url` | string | Yes      | Your HTTPS endpoint URL to receive notifications                    |
| `secret`      | string | No       | Secret key (minimum 16 characters) used to sign and verify payloads |
| `description` | string | No       | Human-readable description for the webhook                          |

#### Field Requirements

* webhook\_url: Must be a valid HTTPS URL. HTTP URLs are not allowed in production.
* secret: Optional. If not provided, a secure secret will be generated automatically. If provided, must be at least 16 characters long. Used for HMAC-SHA512 signature verification.
* description: Optional field for documentation purposes.

#### Generating a Secure Secret

We recommend generating a cryptographically secure random string for your webhook secret. Here are commands for different platforms:

**Linux/Mac (Bash)**

```bash
# Generate a 32-character random string using OpenSSL
openssl rand -hex 16

# Generate a 24-character base64 string
openssl rand -base64 18

# Generate a 32-character random string using /dev/urandom
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1
```

**Windows (PowerShell)**

```powershell
# Generate a 32-character random string
-join ((65..90) + (97..122) + (48..57) | Get-Random -Count 32 | % {[char]$_})

# Generate a base64 string
[Convert]::ToBase64String([System.Security.Cryptography.RandomNumberGenerator]::GetBytes(24))
```

### Response Codes

| Code                        | Description                                                                                      |
| --------------------------- | ------------------------------------------------------------------------------------------------ |
| `201 Created`               | Successfully created the webhook configuration                                                   |
| `400 Bad Request`           | Missing or invalid parameters (e.g., URL is not HTTPS, secret too short, URL already registered) |
| `401 Unauthorized`          | Authentication credentials missing or incorrect                                                  |
| `403 Forbidden`             | User lacks permission to create webhook configurations                                           |
| `500 Internal Server Error` | Server error occurred                                                                            |

### Response Body

| Field         | Type              | Description                                                         |
| ------------- | ----------------- | ------------------------------------------------------------------- |
| `id`          | string (UUID)     | Unique identifier for the webhook configuration                     |
| `webhook_url` | string            | The URL where notifications will be sent                            |
| `description` | string\|null      | The description for the webhook                                     |
| `enabled`     | boolean           | Indicates if the webhook is active (always `true` for new webhooks) |
| `created_at`  | string (datetime) | ISO timestamp when the configuration was created                    |

### Request Example

```bash
curl -L \
  --request POST \
  --url 'https://api.genlogs.io/alerts/webhook' \
  --header 'Access-Token: YOUR_ACCESS-TOKEN' \
  --header 'x-api-key: YOUR_API_KEY'
  --header 'Content-Type: application/json' \
  --data '{
    "webhook_url": "https://example.com",
    "secret": "text",
    "description": "text"
  }'
```

## Create Webhook

> Create webhook settings

```json
{"openapi":"3.1.0","info":{"title":"Alert API","version":"0.0.1"},"security":[{"APIKeyHeader":[]}],"components":{"securitySchemes":{"APIKeyHeader":{"type":"apiKey","description":"JWT Access Token required for authentication","in":"header","name":"Access-Token"}},"schemas":{"WebhookSettingsCreateSchema":{"properties":{"webhook_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Webhook Url"},"secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Secret"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"additionalProperties":false,"type":"object","title":"WebhookSettingsCreateSchema","description":"Schema for creating webhook settings"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/alerts/webhook":{"post":{"tags":["Webhook Alerts"],"summary":"Create Webhook","description":"Create webhook settings","operationId":"create_webhook_alerts_webhook_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSettingsCreateSchema"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```


# Update Alert Webhook

## Update Webhook

The Update Webhook endpoint allows customers to modify an existing webhook configuration, including its URL, secret, description, and enabled status. Since webhooks and alerts are now managed separately, you cannot modify alert rules through this endpoint.

### Authentication

Include the following headers in your requests:

```
Access-Token: <your-access-token>
```

### Permissions

Ensure your API user has a role with `admin` or `edit-alert-webhook-endpoint` permission.

### Endpoint

* **URL**: `https://api.genlogs.io/alerts/webhook/{webhook_id}`
* **Method**: `PATCH`

### URL Parameters

| Parameter    | Type          | Required | Description                                                  |
| ------------ | ------------- | -------- | ------------------------------------------------------------ |
| `webhook_id` | string (UUID) | Yes      | The unique identifier of the webhook configuration to update |

### Request Body

All fields are optional. Only provide the fields you want to change.

| Field         | Type    | Required | Description                                               |
| ------------- | ------- | -------- | --------------------------------------------------------- |
| `webhook_url` | string  | No       | The new HTTPS endpoint URL                                |
| `secret`      | string  | No       | The new secret key (minimum 16 characters)                |
| `description` | string  | No       | The new description                                       |
| `enabled`     | boolean | No       | Set to `true` to enable or `false` to disable the webhook |

#### Field Requirements

* **webhook\_url**: Must be a valid HTTPS URL if provided. Cannot be a URL already registered by this customer.
* **secret**: Must be at least 16 characters long if provided.
* **enabled**: When set to `false`, the webhook will not receive any notifications until re-enabled.

#### Generating a New Secret

If you need to update your webhook secret, refer to the secret generation commands from the Create Webhook documentation.

### Response Codes

| Code                        | Description                                                                    |
| --------------------------- | ------------------------------------------------------------------------------ |
| `200 OK`                    | Successfully updated the webhook configuration                                 |
| `400 Bad Request`           | Missing or invalid parameters (e.g., URL already registered, secret too short) |
| `401 Unauthorized`          | Authentication credentials missing or incorrect                                |
| `403 Forbidden`             | User lacks permission to update webhook configurations                         |
| `404 Not Found`             | Webhook configuration with the specified ID was not found                      |
| `500 Internal Server Error` | Server error occurred                                                          |

### Response Body

The response body has the same structure as the Create Webhook endpoint response, reflecting the updated data.

| Field         | Type              | Description                                      |
| ------------- | ----------------- | ------------------------------------------------ |
| `id`          | string (UUID)     | Unique identifier for the webhook configuration  |
| `webhook_url` | string            | The URL where notifications will be sent         |
| `description` | string\|null      | The description for the webhook                  |
| `enabled`     | boolean           | Indicates if the webhook is active               |
| `created_at`  | string (datetime) | ISO timestamp when the configuration was created |

### Request Examples

```bash
curl -L \
  --request PATCH \
  --url 'https://api.genlogs.io/alerts/webhook/{webhook_id}' \
  --header 'Access-Token: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "webhook_url": "https://example.com",
    "secret": "text",
    "description": "text",
    "enabled": true
  }'
```

## Update Webhook

> Update webhook settings

```json
{"openapi":"3.1.0","info":{"title":"Alert API","version":"0.0.1"},"security":[{"APIKeyHeader":[]}],"components":{"securitySchemes":{"APIKeyHeader":{"type":"apiKey","description":"JWT Access Token required for authentication","in":"header","name":"Access-Token"}},"schemas":{"WebhookSettingsUpdateSchema":{"properties":{"webhook_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Webhook Url"},"secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Secret"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"}},"additionalProperties":false,"type":"object","title":"WebhookSettingsUpdateSchema","description":"Schema for updating webhook settings"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/alerts/webhook/{webhook_id}":{"patch":{"tags":["Webhook Alerts"],"summary":"Update Webhook","description":"Update webhook settings","operationId":"update_webhook_alerts_webhook__webhook_id__patch","parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Webhook Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSettingsUpdateSchema"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

###


# Delete Alert Webhook

Delete an existent Alert Webhook configured for the requester user customer ID

### **Authentication**

* Include your **`Access-Token`** in the header of your requests.
* Include your **`x-api-key`** The API key provided by GenLogs. This header must be included in the request.

### Permissions

The `external-api-delete-alert-webhook-endpoint` permission is required to access this endpoint.

### **Endpoint**

* **URL:**  `https://api.genlogs.io/alerts/webhook/{webhook_id}`
* **Method:** `DELETE`

### **Headers**

* **Access-Token**:  (string, required): Access token obtained from the "Create Access Token" endpoint.
* **X-Api-Key** (string, required): The API key provided by GenLogs.

### Path Params

* **webhook\_id** (string, UUID format,  required): Existent webhook ID, to be deleted.

### Request Example:

```shell
curl --location --request DELETE 'https://api.genlogs.io/alerts/webhook/{webhook_id}' \
--header 'access-token: <your-api-access-token>' \
--header 'x-api-key: <your-x-api-key>' \
```

### **Response:**

* **200 OK:** A JSON object containing the information of the deleted alert webhook.
* **400 Bad Request:** If webhook id is malformed or missing.
* **401 Unauthorized:** If the authentication credentials (Access-Token) is missing or incorrect.
* **403 Forbidden**: If the permission has not been added to your user.
* **404 Not Found**: If the provided `webhook_id` doesn't exist or not belongs to the customer.
* **500 Internal Server Error:** If there is an issue on the server that prevents processing the request.

### **Response Body:**

200 OK – Webhook Deleted Successfully

```json
{
    "id": "0a7f4670-aeed-491a-91ae-af7e88b397b3",
    "webhook_url": "https://example.domain/webhooks/genlogs-alerts",
    "description": "test-to-be-deleted",
    "created_at": "2026-02-20T18:58:19.132530",
    "deleted": true
}
```

400 Bad Request

Returned when:

* The provided webhook id is malformed or missing

```json
{
    "message": "Invalid webhook ID format.",
    "error_code": "VALIDATION_ERROR"
}
```

401 Unauthorized

* When access-token is missing or expired

```json
{
    "detail": "Token is missing!"
}
```

```json
{
    "detail": "Token is expired!"
}
```

403 Forbidden

```json
{
    "detail": "User not allowed to access this endpoint"
}
```

404 Not Found

* When the webhook is is not found or does not belong to customer

```json
{
    "message": "Webhook 0a7f4670-aeed-491a-91ae-af7e88b397b3 not found or does not belong to customer",
    "error_type": "WebhookNotFoundError",
    "error_code": "WEBHOOK_NOT_FOUND"
}
```

## Delete alert webhook

> Delete an alert webhook by ID. Requires ownership for the authenticated customer. Returns the deleted webhook data (id, webhook\_url, description, created\_at). Requires admin or external-api-delete-alert-webhook-endpoint.<br>

```json
{"openapi":"3.0.3","info":{"title":"Alert API - Delete Webhook","version":"1.0.0"},"paths":{"/alerts/webhook/{webhook_id}":{"delete":{"summary":"Delete alert webhook","description":"Delete an alert webhook by ID. Requires ownership for the authenticated customer. Returns the deleted webhook data (id, webhook_url, description, created_at). Requires admin or external-api-delete-alert-webhook-endpoint.\n","operationId":"deleteAlertWebhook","parameters":[{"in":"header","name":"Access-Token","required":true,"schema":{"type":"string"},"description":"JWT access token for authentication"},{"in":"header","name":"X-API-Key","required":true,"schema":{"type":"string"},"description":"API key for authentication"},{"in":"path","name":"webhook_id","required":true,"schema":{"type":"string","format":"uuid"},"description":"UUID of the webhook to delete"}],"responses":{"200":{"description":"Webhook deleted successfully; returns deleted webhook data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedWebhookResponse"}}}},"400":{"description":"Bad Request – invalid webhook ID format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized – missing or invalid token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden – insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found – webhook does not exist or does not belong to customer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"DeletedWebhookResponse":{"type":"object","description":"Deleted webhook data returned on successful DELETE (secret and enabled excluded)","properties":{"id":{"type":"string","format":"uuid"},"webhook_url":{"type":"string","format":"uri"},"description":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"deleted":{"type":"boolean","description":"Always true for delete response"}},"required":["id","webhook_url","created_at","deleted"]},"ErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"error_code":{"type":"string","description":"Machine-readable error code"}},"required":["message"]}}}}
```


# Test Webhook

## Test Webhook Endpoint

The Test Webhook endpoint allows customers to send a sample test payload to a given URL to verify its connectivity and signature validation logic before creating a webhook configuration. This helps ensure your webhook handler is working correctly.

### Authentication

Include the following headers in your requests:

```
Access-Token: <your-access-token>
```

### Permissions

Ensure your API user has a role with `admin` or `test-alert-webhook-endpoint` permission.

### Endpoint

* **URL**: `https://api.genlogs.io/alerts/webhook/test`
* **Method**: `POST`

### Request Body

| Field         | Type   | Required | Description                                           |
| ------------- | ------ | -------- | ----------------------------------------------------- |
| `webhook_url` | string | Yes      | The HTTPS URL to send the test payload to             |
| `secret`      | string | Yes      | The secret that will be used to sign the test payload |

### Request example

```
curl --location 'https://api.genlogs.io/alerts/webhook/test' \
--header 'access-token: <access-token>' \
--header 'x-api-key: <x-api-key>' \
--header 'Content-Type: application/json' \
--data '{
    "webhook_url": "https://example-host.com/webhooks/genlogs-alerts",
    "secret": {your-webhook-secret}
}'
```

#### Field Requirements

* **webhook\_url**: Must be a valid HTTPS URL that can receive POST requests
* **secret**: Must be at least 16 characters long (same as used for webhook creation)

### Response Codes

| Code                        | Description                                                                       |
| --------------------------- | --------------------------------------------------------------------------------- |
| `200 OK`                    | The test was sent successfully and your endpoint responded with a 2xx status code |
| `400 Bad Request`           | The provided URL or secret is invalid                                             |
| `401 Unauthorized`          | Authentication credentials missing or incorrect                                   |
| `403 Forbidden`             | User lacks permission to test webhooks                                            |
| `500 Internal Server Error` | The test failed (timeout, non-2xx response, connection error, etc.)               |

### Response Body

#### Success Response

| Field     | Type    | Description                                          |
| --------- | ------- | ---------------------------------------------------- |
| `success` | boolean | `true` if the test was successful                    |
| `status`  | integer | HTTP status code (always `200` for successful tests) |
| `message` | string  | Success confirmation message                         |

#### Error Response

| Field     | Type    | Description                                         |
| --------- | ------- | --------------------------------------------------- |
| `success` | boolean | `false` when the test failed                        |
| `status`  | integer | HTTP status code (typically `500` for failed tests) |
| `message` | string  | Error description explaining why the test failed    |

### Test Payload Structure

The test endpoint sends a sample payload with the following structure to verify your webhook handler:

```json
{
  "event": "alert.test",
  "webhook_id": "test-webhook-id",
  "customer_id": 123,
  "alert_details": [{
    "alert_name": "Test Alert",
    "email": "test@example.com",
    "description": "This is a test alert"
  }],
  "matches": [{
    "result_url": "https://app.genlogs.com/search/result/test",
    "front_view_url": "https://example.com/image1.jpg",
    "side_view_url": "https://example.com/image2.jpg",
    "rear_view_url": "https://example.com/image3.jpg",
    "time": "2024-01-01T12:00:00Z",
    "city": "Test City",
    "state": "TS",
    "road": "Test Road",
    "lat_long": "40.7128, -74.0060",
    "license_plate": "TEST123",
    "vin": "1HGBH41JXMN109186",
    "usdot": "123456",
    "mc": "MC-123456",
    "cab_number": "CAB123",
    "trailer_logo": "Test Logo",
    "trailer_number": "TRL123",
    "deep_search": "Test Match"
  }],
  "total_matches": 1,
  "timestamp": "2024-01-01T12:01:00.123456+00:00"
}
```

### Request Examples

## Validate Webhook Endpoint

> Test a webhook endpoint with a sample alert payload

```json
{"openapi":"3.1.0","info":{"title":"Alert API","version":"0.0.1"},"security":[{"APIKeyHeader":[]}],"components":{"securitySchemes":{"APIKeyHeader":{"type":"apiKey","description":"JWT Access Token required for authentication","in":"header","name":"Access-Token"}},"schemas":{"WebhookTestSchema":{"properties":{"webhook_url":{"type":"string","maxLength":2083,"minLength":1,"format":"uri","title":"Webhook Url"},"secret":{"type":"string","title":"Secret"}},"additionalProperties":false,"type":"object","required":["webhook_url","secret"],"title":"WebhookTestSchema","description":"Schema for testing webhook endpoints"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"paths":{"/alerts/webhook/test":{"post":{"tags":["Webhook Alerts"],"summary":"Validate Webhook Endpoint","description":"Test a webhook endpoint with a sample alert payload","operationId":"validate_webhook_endpoint_alerts_webhook_test_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTestSchema"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}}}
```

### Response Examples

#### Success Response (200 OK)

```json
{
  "success": true,
  "status": 200,
  "message": "Webhook test successful"
}
```

#### Error Response (500 Internal Server Error)

```json
{
  "success": false,
  "status": 500,
  "message": "Webhook test failed: Connection timeout"
}
```

### Signature Validation Example

```python
import hmac
import hashlib

def verify_signature(payload_body: bytes, signature_header: str, secret: str) -> bool:
    """Verifies the HMAC-SHA512 signature of a webhook payload."""
    if not signature_header:
        return False
    
    hash_object = hmac.new(
        secret.encode('utf-8'),
        msg=payload_body,
        digestmod=hashlib.sha512
    )
    expected_signature = "sha512=" + hash_object.hexdigest()
    
    return hmac.compare_digest(expected_signature, signature_header)

# Usage in your webhook handler
signature = request.headers.get('X-GenLogs-Signature')
payload_body = request.get_data()  # Raw bytes
webhook_secret = "your-super-secret-key-at-least-16-chars"

if verify_signature(payload_body, signature, webhook_secret):
    # Signature is valid, process the webhook
    payload = request.get_json()
    return {"status": "success"}, 200
else:
    # Invalid signature
    return {"error": "Invalid signature"}, 401
```

### What to Verify in Your Webhook Handler

When you receive the test payload, verify:

1. **Signature Verification**: Ensure you can properly verify the HMAC-SHA512 signature in the `X-GenLogs-Signature` header
2. **JSON Parsing**: Confirm you can parse the JSON payload correctly
3. **Response Time**: Respond within 5 seconds (the webhook timeout)
4. **HTTP Status**: Return a 2xx status code to indicate success
5. **Headers**: Check that you receive all expected headers:
   * `Content-Type: application/json`
   * `User-Agent: GenLogs-Webhook/1.0`
   * `X-GenLogs-Signature: sha512=...`
   * `X-GenLogs-Event: alert.test`
   * `X-GenLogs-Timestamp: ...`

### Common Test Failure Reasons

* **Connection timeout** (webhook endpoint not responding within 5 seconds)
* **Invalid SSL certificate** on the webhook URL
* **Non-2xx HTTP response** from your endpoint
* **Connection refused** (endpoint not accessible)
* **DNS resolution failure** for the webhook URL
* **Invalid URL format** or non-HTTPS URL


# List Alert Webhooks

### List Webhooks

Retrieve a list of all webhook configurations registered for your customer. This endpoint returns the webhook IDs, URLs, creation timestamps, and descriptions, allowing you to identify which webhooks are configured and manage them accordingly.

#### Authentication

Include the following headers in your requests:

```
Access-Token: <your-access-token>
```

#### Permissions

Ensure your API user has a role with `external-api-get-webhook-list` permission.

#### Endpoint

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

#### Request Parameters

This endpoint does not require any query parameters or request body. The `customer_id` is automatically extracted from your access token.

#### Response Codes

| Code                        | Description                                               |
| --------------------------- | --------------------------------------------------------- |
| `200 OK`                    | Successfully retrieved the list of webhook configurations |
| `401 Unauthorized`          | Authentication credentials missing or incorrect           |
| `403 Forbidden`             | User lacks permission to list webhook configurations      |
| `500 Internal Server Error` | Server error occurred                                     |

#### Response Body

The response is an array of webhook objects. Each object contains:

| Field         | Type              | Description                                      |
| ------------- | ----------------- | ------------------------------------------------ |
| `id`          | string (UUID)     | Unique identifier for the webhook configuration  |
| `created_at`  | string (datetime) | ISO timestamp when the configuration was created |
| `webhook_url` | string            | The URL where notifications are sent             |
| `description` | string\|null      | Human-readable description for the webhook       |

**Response Example**

```json
[
  {
    "id": "0f8a681f-48ce-44f0-8e27-b8311c17b12a",
    "created_at": "2025-09-23T21:37:30.173622",
    "webhook_url": "https://example.com/webhook",
    "description": "Production webhook endpoint"
  },
  {
    "id": "1a2b3c4d-5e6f-7890-abcd-ef1234567890",
    "created_at": "2025-09-24T10:15:00.000000",
    "webhook_url": "https://another.example.com/webhook",
    "description": "Development webhook endpoint"
  },
  {
    "id": "2b3c4d5e-6f78-9012-bcde-f12345678901",
    "created_at": "2025-09-25T14:20:15.123456",
    "webhook_url": "https://staging.example.com/webhook",
    "description": null
  },
  ...
]
```

**Empty Response**

If no webhooks are registered for your organization, the endpoint returns an empty array:

```json
[]
```

#### Request Example

```bash
curl -L \
  --request GET \
  --url 'https://api.genlogs.io/alerts/webhook' \
  --header 'Access-Token: YOUR_ACCESS_TOKEN' \
  --header 'x-api-key: YOUR_API_KEY'
```

#### Notes

* The response only includes webhooks registered for your organization (determined by the `customer_id` in your access token).
* The `secret` field is not included in the response for security reasons.
* Use the `id` field to reference specific webhooks when updating or managing them via other endpoints.
* The `created_at` timestamp helps identify when each webhook was registered.

> List all webhooks for the authenticated customer

## List Webhooks

> List all webhooks for the authenticated customer

```json
{"openapi":"3.1.0","info":{"title":"Alert API","version":"0.0.1"},"security":[{"APIKeyHeader":[]}],"components":{"securitySchemes":{"APIKeyHeader":{"type":"apiKey","description":"JWT Access Token required for authentication","in":"header","name":"Access-Token"}}},"paths":{"/alerts/webhook":{"get":{"tags":["Webhook Alerts"],"summary":"List Webhooks","description":"List all webhooks for the authenticated customer","operationId":"list_webhooks_alerts_webhook_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"type":"object"},"type":"array","title":"Response List Webhooks Alerts Webhook Get"}}}}}}}}}
```


